From patchwork Fri Jan 31 06:17:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Morton X-Patchwork-Id: 11359357 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CB0FD139A for ; Fri, 31 Jan 2020 06:17:23 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 8E3AE24682 for ; Fri, 31 Jan 2020 06:17:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=kernel.org header.i=@kernel.org header.b="A81u8slx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8E3AE24682 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=linux-foundation.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 40C3E6B059D; Fri, 31 Jan 2020 01:17:22 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 3BD586B059F; Fri, 31 Jan 2020 01:17:22 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2D34F6B05A0; Fri, 31 Jan 2020 01:17:22 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0218.hostedemail.com [216.40.44.218]) by kanga.kvack.org (Postfix) with ESMTP id 168376B059D for ; Fri, 31 Jan 2020 01:17:22 -0500 (EST) Received: from smtpin15.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay01.hostedemail.com (Postfix) with ESMTP id C03F4180AD802 for ; Fri, 31 Jan 2020 06:17:21 +0000 (UTC) X-FDA: 76436922282.15.shape70_40396466d9927 X-Spam-Summary: 30,2,0,ef4b3e539add56d8,d41d8cd98f00b204,akpm@linux-foundation.org,:akpm@linux-foundation.org:cmetcalf@tilera.com:krzysiek@podlesie.net::mm-commits@vger.kernel.org:nivedita@alum.mit.edu:torvalds@linux-foundation.org,RULES_HIT:41:305:355:379:800:960:967:968:973:988:989:1260:1263:1345:1359:1381:1431:1437:1535:1544:1711:1714:1730:1747:1777:1792:2198:2199:2393:2525:2559:2563:2682:2685:2693:2859:2902:2933:2937:2939:2942:2945:2947:2951:2954:3022:3138:3139:3140:3141:3142:3351:3865:3866:3867:3868:3870:3871:3872:3874:3934:3936:3938:3941:3944:3947:3950:3953:3956:3959:4321:5007:6261:6653:7576:7875:7903:8599:9025:9545:10010:10913:11026:11658:11914:12043:12048:12296:12297:12517:12519:12555:12679:12783:12986:13053:13153:13161:13228:13229:14093:14181:14721:14849:21080:21451:21627:21939:21990:30012:30025:30054:30069:30070:30079,0,RBL:error,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:1:0,LFtime:26,LUA_SU MMARY:no X-HE-Tag: shape70_40396466d9927 X-Filterd-Recvd-Size: 5940 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by imf41.hostedemail.com (Postfix) with ESMTP for ; Fri, 31 Jan 2020 06:17:21 +0000 (UTC) Received: from localhost.localdomain (c-73-231-172-41.hsd1.ca.comcast.net [73.231.172.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 5EBA324682; Fri, 31 Jan 2020 06:17:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1580451440; bh=3JFy2JqsNWUySaaKsdjwb8mxonZy0t095tsLVz68yZ4=; h=Date:From:To:Subject:In-Reply-To:From; b=A81u8slxVqSbJOPgdNMfeWXin9WX8v2Hxq+6Se4NfUNJTaH+1Hg6d8xLKkuwMw5UB tAkb0rPD377bvCPsaJQ/P6aaePFGR0sSd2VnPd1sS1f8kZK9fCfLQbfQIurgjxvkH4 5pJMNwSofzm5gkzn/xQ6asoriAY/YNk0tgRBQDxk= Date: Thu, 30 Jan 2020 22:17:19 -0800 From: Andrew Morton To: akpm@linux-foundation.org, cmetcalf@tilera.com, krzysiek@podlesie.net, linux-mm@kvack.org, mm-commits@vger.kernel.org, nivedita@alum.mit.edu, torvalds@linux-foundation.org Subject: [patch 113/118] init/main.c: fix quoted value handling in unknown_bootoption Message-ID: <20200131061719.aCBYofV-k%akpm@linux-foundation.org> In-Reply-To: <20200130221021.5f0211c56346d5485af07923@linux-foundation.org> User-Agent: s-nail v14.8.16 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: Arvind Sankar Subject: init/main.c: fix quoted value handling in unknown_bootoption Patch series "init/main.c: minor cleanup/bugfix of envvar handling", v2. unknown_bootoption passes unrecognized command line arguments to init as either environment variables or arguments. Some of the logic in the function is broken for quoted command line arguments. When an argument of the form param="value" is processed by parse_args and passed to unknown_bootoption, the command line has param\0"value\0 with val pointing to the beginning of value. The helper function repair_env_string is then used to restore the '=' character that was removed by parse_args, and strip the quotes off fully. This results in param=value\0\0 and val ends up pointing to the 'a' instead of the 'v' in value. This bug was introduced when repair_env_string was refactored into a separate function, and the decrement of val in repair_env_string became dead code. This causes two problems in unknown_bootoption in the two places where the val pointer is used as a substitute for the length of param: 1. An argument of the form param=".value" is misinterpreted as a potential module parameter, with the result that it will not be placed in init's environment. 2. An argument of the form param="value" is checked to see if param is an existing environment variable that should be overwritten, but the comparison is off-by-one and compares 'param=v' instead of 'param=' against the existing environment. So passing, for example, TERM="vt100" on the command line results in init being passed both TERM=linux and TERM=vt100 in its environment. Patch 1 adds logging for the arguments and environment passed to init and is independent of the rest: it can be dropped if this is unnecessarily verbose. Patch 2 removes repair_env_string from initcall parameter parsing in do_initcall_level, as that uses a separate copy of the command line now and the repairing is no longer necessary. Patch 3 fixes the bug in unknown_bootoption by recording the length of param explicitly instead of implying it from val-param. This patch (of 3): Commit a99cd1125189 ("init: fix bug where environment vars can't be passed via boot args") introduced two minor bugs in unknown_bootoption by factoring out the quoted value handling into a separate function. When value is quoted, repair_env_string will move the value up 1 byte to strip the quotes, so val in unknown_bootoption no longer points to the actual location of the value. The result is that an argument of the form param=".value" is mistakenly treated as a potential module parameter and is not placed in init's environment, and an argument of the form param="value" can result in a duplicate environment variable: eg TERM="vt100" on the command line will result in both TERM=linux and TERM=vt100 being placed into init's environment. Fix this by recording the length of the param before calling repair_env_string instead of relying on val. Link: http://lkml.kernel.org/r/20191212180023.24339-4-nivedita@alum.mit.edu Signed-off-by: Arvind Sankar Cc: Chris Metcalf Cc: Krzysztof Mazur Signed-off-by: Andrew Morton --- init/main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) --- a/init/main.c~init-mainc-fix-quoted-value-handling-in-unknown_bootoption +++ a/init/main.c @@ -255,7 +255,6 @@ static void __init repair_env_string(cha else if (val == param+strlen(param)+2) { val[-2] = '='; memmove(val-1, val, strlen(val)+1); - val--; } else BUG(); } @@ -290,6 +289,8 @@ static int __init set_init_arg(char *par static int __init unknown_bootoption(char *param, char *val, const char *unused, void *arg) { + size_t len = strlen(param); + repair_env_string(param, val); /* Handle obsolete-style parameters */ @@ -297,7 +298,7 @@ static int __init unknown_bootoption(cha return 0; /* Unused module parameter. */ - if (strchr(param, '.') && (!val || strchr(param, '.') < val)) + if (strnchr(param, len, '.')) return 0; if (panic_later) @@ -311,7 +312,7 @@ static int __init unknown_bootoption(cha panic_later = "env"; panic_param = param; } - if (!strncmp(param, envp_init[i], val - param)) + if (!strncmp(param, envp_init[i], len+1)) break; } envp_init[i] = param;