Message ID | 1479755377-12442-1-git-send-email-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
On Nov 21 2016, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > diff --git a/posix/execvpe.c b/posix/execvpe.c > index d933f9c..96a12bf5 100644 > --- a/posix/execvpe.c > +++ b/posix/execvpe.c > @@ -41,19 +41,20 @@ maybe_script_execute (const char *file, char *const argv[], char *const envp[]) > ptrdiff_t argc = 0; > while (argv[argc++] != NULL) > { > - if (argc == INT_MAX - 1) > + if (argc == INT_MAX - 2) > { > errno = E2BIG; > return; > } > } > > - /* Construct an argument list for the shell. */ > - char *new_argv[argc + 1]; > + /* Construct an argument list for the shell. It will contain at minimum 3 > + arguments (current shell, script, and an ending NULL. */ > + char *new_argv[argc + 2]; The array is now always one element too big, unless execvpe was called with argv[0] == NULL. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different."
On Nov 21 2016, Adhemerval Zanella <adhemerval.zanella@linaro.org> wrote: > @@ -91,10 +92,11 @@ __execvpe (const char *file, char *const argv[], char *const envp[]) > /* Although GLIBC does not enforce NAME_MAX, we set it as the maximum > size to avoid unbounded stack allocation. Same applies for > PATH_MAX. */ > - size_t file_len = __strnlen (file, NAME_MAX + 1); > + size_t file_len = __strnlen (file, NAME_MAX) + 1; > size_t path_len = __strnlen (path, PATH_MAX - 1) + 1; > > - if ((file_len > NAME_MAX) > + /* NAME_MAX does not include the terminating null character. */ > + if (((file_len-1) > NAME_MAX) Spaces around operator and remove redundant parens. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
diff --git a/posix/execvpe.c b/posix/execvpe.c index d933f9c..96a12bf5 100644 --- a/posix/execvpe.c +++ b/posix/execvpe.c @@ -41,19 +41,20 @@ maybe_script_execute (const char *file, char *const argv[], char *const envp[]) ptrdiff_t argc = 0; while (argv[argc++] != NULL) { - if (argc == INT_MAX - 1) + if (argc == INT_MAX - 2) { errno = E2BIG; return; } } - /* Construct an argument list for the shell. */ - char *new_argv[argc + 1]; + /* Construct an argument list for the shell. It will contain at minimum 3 + arguments (current shell, script, and an ending NULL. */ + char *new_argv[argc + 2]; new_argv[0] = (char *) _PATH_BSHELL; new_argv[1] = (char *) file; if (argc > 1) - memcpy (new_argv + 2, argv + 1, argc * sizeof(char *)); + memcpy (new_argv + 2, argv + 1, (argc - 1) * sizeof(char *)); else new_argv[2] = NULL; @@ -91,10 +92,11 @@ __execvpe (const char *file, char *const argv[], char *const envp[]) /* Although GLIBC does not enforce NAME_MAX, we set it as the maximum size to avoid unbounded stack allocation. Same applies for PATH_MAX. */ - size_t file_len = __strnlen (file, NAME_MAX + 1); + size_t file_len = __strnlen (file, NAME_MAX) + 1; size_t path_len = __strnlen (path, PATH_MAX - 1) + 1; - if ((file_len > NAME_MAX) + /* NAME_MAX does not include the terminating null character. */ + if (((file_len-1) > NAME_MAX) || !__libc_alloca_cutoff (path_len + file_len + 1)) { errno = ENAMETOOLONG; @@ -103,6 +105,9 @@ __execvpe (const char *file, char *const argv[], char *const envp[]) const char *subp; bool got_eacces = false; + /* The resulting string maximum size would be potentially a entry + in PATH plus '/' (path_len + 1) and then the the resulting file name + plus '\0' (file_len since it already accounts for the '\0'). */ char buffer[path_len + file_len + 1]; for (const char *p = path; ; p = subp) { @@ -123,7 +128,7 @@ __execvpe (const char *file, char *const argv[], char *const envp[]) execute. */ char *pend = mempcpy (buffer, p, subp - p); *pend = '/'; - memcpy (pend + (p < subp), file, file_len + 1); + memcpy (pend + (p < subp), file, file_len); __execve (buffer, argv, envp);