From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-qk1-x72e.google.com (mail-qk1-x72e.google.com [IPv6:2607:f8b0:4864:20::72e]) by sourceware.org (Postfix) with ESMTPS id 8586D3858D33 for ; Mon, 12 Apr 2021 20:59:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 8586D3858D33 Received: by mail-qk1-x72e.google.com with SMTP id d15so2799770qkc.9 for ; Mon, 12 Apr 2021 13:59:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=yn8ja5s1ctw4/HQpq4g6drg0UHL0veKjPdWGoqZQ/G0=; b=g6hnqF6EsdupnuGgv44xNnCqyp8Mw5ODHUxxxRE2kEvWr5mlTZcLxZLt9385HA8GCA fCFT339uPNJYFGk4jZU44jovXR/MGu6LrQRJKDfBfYCKAprZpxgzwC63+PFJr0mo1xG8 fqzuJvg5xh8wInJ+q4ZetK6Hv5fudVtWQj6SJCPYib86hWTVrN3MD+XDD3xadwoEE+or oT4kmeXkCLzWvW5gb/Cru7+Hdugo4viFy/j4OVDVIdqJXF71ytLwVQZdBfLf3seuZ2Mx /cBD3xKaZqsuWVl4JCUqRBc7khpwj6f1IrMw4vLc42SYBmu6vE8qlyM1/us6bf+kywCN IK1g== X-Gm-Message-State: AOAM533oE4pUAODR0AEhbZj3b11gyTRNZQCBcf7xMJJTpTb0AK78NquA eLQTpJXq1d0ACOTN6XxkveVUGDqBRZDk0hik X-Google-Smtp-Source: ABdhPJwP3/SCXPM7J0/s4r0abZyzVMJ7uTI4a88tqhlXYtEBg51Dje7lbeuC4hXmVvMUBQJ/nWaY8A== X-Received: by 2002:a05:620a:408d:: with SMTP id f13mr9339506qko.312.1618261151909; Mon, 12 Apr 2021 13:59:11 -0700 (PDT) Received: from [192.168.1.132] ([177.194.41.149]) by smtp.gmail.com with ESMTPSA id m3sm8649626qkk.15.2021.04.12.13.59.10 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 12 Apr 2021 13:59:11 -0700 (PDT) Subject: Re: [PATCH] linux: sysconf: limit _SC_MAX_ARG to 6 MiB [BZ #25305] To: Michal Nazarewicz , libc-alpha@sourceware.org References: <20210407151058.1176364-1-mina86@mina86.com> From: Adhemerval Zanella Message-ID: <46c3ea60-7a57-14f7-92f9-e915e3b12dae@linaro.org> Date: Mon, 12 Apr 2021 17:59:09 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1 MIME-Version: 1.0 In-Reply-To: <20210407151058.1176364-1-mina86@mina86.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Apr 2021 20:59:14 -0000 On 07/04/2021 12:10, Michal Nazarewicz wrote: > Since Linux 4.13, kernel limits the maximum command line arguments > length to 6 MiB.¹ Normally the limit is still quarter of the maximum > stack size but if that limit exceeds 6 MiB it’s clamped down. > > glibc’s __sysconf implementation for Linux platform is not aware of > this limitation and for stack sizes of over 24 MiB it returns higher > ARG_MAX than Linux will actually accept. This can be verified by > executing the following application on Linux 4.13 or newer: > > #include > #include > #include > #include > #include > > int main(void) { > const struct rlimit rlim = { 40 * 1024 * 1024, > 40 * 1024 * 1024 }; > if (setrlimit(RLIMIT_STACK, &rlim) < 0) { > perror("setrlimit: RLIMIT_STACK"); > return 1; > } > > printf("ARG_MAX : %8ld\n", sysconf(_SC_ARG_MAX)); > printf("63 * 100 KiB: %8ld\n", 63L * 100 * 1024); > printf("6 MiB : %8ld\n", 6L * 1024 * 1024); > > char str[100 * 1024], *argv[64], *envp[1]; > memset(&str, 'A', sizeof str); > str[sizeof str - 1] = '\0'; > for (size_t i = 0; i < sizeof argv / sizeof *argv - 1; ++i) { > argv[i] = str; > } > argv[sizeof argv / sizeof *argv - 1] = envp[0] = 0; > > execve("/bin/true", argv, envp); > perror("execve"); > return 1; > } > > On affected systems the program will report ARG_MAX as 10 MiB but > despite that executing /bin/true with a bit over 6 MiB of command line > arguments will fail with E2BIG error. Expected result is that ARG_MAX > is reported as 6 MiB. > > Update the __sysconf function to clamp ARG_MAX value to 6 MiB if it > would otherwise exceed it. This resolves bug #25305 which was market > WONTFIX as suggested solution was to cap ARG_MAX at 128 KiB. > > As an aside and point of comparison, bionic (a libc implementation for > Android systems) decided to resolve this issue by always returning 128 > KiB ignoring any potential xargs regressions.² > > On older kernels this results in returning overly conservative value > but that’s a safer option than being aggressive and returning invalid > value on recent systems. It’s also worth noting that at this point > all supported Linux releases have the 6 MiB barrier so only someone > running an unsupported kernel version would get incorrectly truncated > result. > > ¹ See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=da029c11e6b12f321f36dac8771e833b65cec962 > ² See https://android.googlesource.com/platform/bionic/+/baed51ee3a13dae4b87b11870bdf7f10bdc9efc1 Patch look good to me, thanks. Reviewed=by: Adhemerval Zanella > --- > sysdeps/unix/sysv/linux/sysconf.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/sysdeps/unix/sysv/linux/sysconf.c b/sysdeps/unix/sysv/linux/sysconf.c > index 366fcef01e..bd711795c7 100644 > --- a/sysdeps/unix/sysv/linux/sysconf.c > +++ b/sysdeps/unix/sysv/linux/sysconf.c > @@ -55,7 +55,10 @@ __sysconf (int name) > struct rlimit rlimit; > /* Use getrlimit to get the stack limit. */ > if (__getrlimit (RLIMIT_STACK, &rlimit) == 0) > - return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4); > + { > + const long int limit = MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4); > + return MIN (limit, 6 << 10 << 10); I think it a bit easier to read with the value expanded (6291456). > + } > > return legacy_ARG_MAX; > } >