summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2025-11-14 13:58:58 +0000
committerCollin Funk <collin.funk1@gmail.com>2025-11-17 11:57:07 -0800
commitefc8642051e6c4fe5165e8986c1338ba2c180de6 (patch)
tree05bfbaf67496fa2a2dca30b47e8a4ba5930e15d9
parent03db4466593b9bbf7bce59cd8d4b82434bafa0cd (diff)
posix: execvpe: fix UMR with file > NAME_MAX [BZ #33627]
* posix/execvpe.c (__execvpe_common): Since strnlen doesn't inspect beyond NAME_MAX and NAME_MAX does not cover the NUL, we need to explicitly check for the NUL. I.e. the existing check for, file_len-1 > NAME_MAX, was never true. This check is required so that we're guaranteed that file_len includes the NUL, as we depend on that in the following memcpy to properly terminate the file buffer passed to execve(). Otherwise that call will trigger UMR when inspecting the passed file, which can be seen with valgrind. Note returning ENAMETOOLONG early here for FILE names > NAME_MAX will also avoid redundant processing of ENAMETOOLONG on each entry in $PATH, after the change in [BZ #33626] is applied. Reviewed-by: Collin Funk <collin.funk1@gmail.com>
-rw-r--r--posix/execvpe.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/posix/execvpe.c b/posix/execvpe.c
index c139dfe8fd..de5fc14eda 100644
--- a/posix/execvpe.c
+++ b/posix/execvpe.c
@@ -98,8 +98,9 @@ __execvpe_common (const char *file, char *const argv[], char *const envp[],
size_t file_len = __strnlen (file, NAME_MAX) + 1;
size_t path_len = __strnlen (path, PATH_MAX - 1) + 1;
- /* NAME_MAX does not include the terminating null character. */
- if ((file_len - 1 > NAME_MAX)
+ /* NAME_MAX does not include the terminating NUL character.
+ The following check ensures FILE is NUL terminated. */
+ if ((file_len - 1 == NAME_MAX && file[NAME_MAX] != '\0')
|| !__libc_alloca_cutoff (path_len + file_len + 1))
{
errno = ENAMETOOLONG;