public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: Michal Nazarewicz <mina86@mina86.com>, libc-alpha@sourceware.org
Subject: Re: [PATCH] linux: sysconf: limit _SC_MAX_ARG to 6 MiB [BZ #25305]
Date: Mon, 12 Apr 2021 17:59:09 -0300	[thread overview]
Message-ID: <46c3ea60-7a57-14f7-92f9-e915e3b12dae@linaro.org> (raw)
In-Reply-To: <20210407151058.1176364-1-mina86@mina86.com>



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 <stdio.h>
>     #include <string.h>
>     #include <sys/resource.h>
>     #include <sys/time.h>
>     #include <unistd.h>
> 
>     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  <adhemerval.zanella@linaro.org>

> ---
>  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;
>        }
> 

  parent reply	other threads:[~2021-04-12 20:59 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-07 15:10 Michal Nazarewicz
2021-04-07 18:36 ` Adhemerval Zanella
2021-04-07 18:41   ` Florian Weimer
2021-04-07 18:52     ` Adhemerval Zanella
2021-04-07 19:04       ` Florian Weimer
2021-04-07 19:34         ` Adhemerval Zanella
2021-04-07 19:36           ` Florian Weimer
2021-04-08  1:49           ` Michal Nazarewicz
2021-04-12 20:59 ` Adhemerval Zanella [this message]
2021-04-12 21:31   ` Michal Nazarewicz
2021-04-13 11:53     ` Adhemerval Zanella
2021-04-13 12:13     ` Andreas Schwab
2021-04-13 13:36       ` Adhemerval Zanella
2021-04-13 14:41         ` Andreas Schwab
2021-04-13 14:45           ` Adhemerval Zanella
2021-04-13 19:57         ` Michal Nazarewicz
2021-04-13 20:47           ` Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46c3ea60-7a57-14f7-92f9-e915e3b12dae@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=libc-alpha@sourceware.org \
    --cc=mina86@mina86.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).