On Wed, 2023-10-11 at 12:41 +0200, Alejandro Colomar wrote: > Hi Rik, > > On Tue, Oct 10, 2023 at 11:41:53PM -0400, Rik van Riel wrote: > > Document that if a command line or environment string is too long > > (> MAX_ARG_STRLEN), execve will also return E2BIG. > > That's already implied by the current text: > > E2BIG The total number of bytes in the environment (envp) and > argument > list (argv) is too large. > > That means that > > size_t bytes; > > bytes = 0; > for (char *e = envp; e != NULL; e++) > bytes += strlen(e) + 1; // I have doubts about the +1 > for (char *a = argv; a != NULL; a++) > bytes += strlen(a) + 1; // Same doubts > > if (bytes > MAX_ARG_STRLEN) // Maybe >= ? > return -E2BIG; The code in fs/exec.c enforces MAX_ARG_STRLEN against each individual string, not against the total. If any string, either argument or environment, is larger than 32 * PAGE_SIZE, the kernel will return -E2BIG. do_execveat_common() has this code, which uses copy_strings to copy both the strings from the environment, and from the command line arguments: retval = copy_strings(bprm->envc, envp, bprm); if (retval < 0) goto out_free; retval = copy_strings(bprm->argc, argv, bprm); if (retval < 0) goto out_free; Inside copy_strings() we have this code: while (argc-- > 0) { ... len = strnlen_user(str, MAX_ARG_STRLEN); if (!len) goto out; ret = -E2BIG; if (!valid_arg_len(bprm, len)) goto out; The valid_arg_len() function does not need explanation: static bool valid_arg_len(struct linux_binprm *bprm, long len) { return len <= MAX_ARG_STRLEN; } The current man page wording is very clear about the total length being enforced, but IMHO not as clear about the limit that gets enforced on each individual string. The total length limit of environment & commandline arguments is enforced by bprm_stack_limits(), and is checked against either 1/4 of the maximum stack size, or 3/4 of _STK_LIM, whichever is smaller. The MAX_ARG_STRLEN value does not come into play when enforcing the total. -- All Rights Reversed.