On 07/11/2025 15:42, Pádraig Brady wrote:
On 07/11/2025 12:22, Bruno Haible wrote:I wrote:$ ./configure gl_cv_func_posix_spawnp_secure_exec=no --quietI reproduce it. Smaller reproducer: $ cd src $ mkdir subdir $ ./ginstall -s -c -m 555 dd subdir It crashes if and only if $PATH is long enough:I can force the crash using the attached testcase.sh, that sets a PATH of size ca. 4 KB, on - Linux/SPARC - Linux/ppc64, Linux/ppc64le - Solaris 10 and 11 / SPARC I'm committing this fix, which fixes the problem on all these platforms.Excellent. The code looks good to me. I'll add the following to our test script: +# Ensure there are no issues with posix_spawnp() and large $PATHs +# which we saw when initially changing from execvp() to posix_spawnp(). +PATH=$(printf '%4001s' '' | sed 's/\(.\{79\}\)./\1:/g'):$PATH \ + ginstall $strip -c -m 555 $dd $dir || fail=1
Note the sed above that splits the long path into acceptable length components shouldn't be needed ideally. Each $PATH component needs to be <= $NAME_MAX: $ getconf -a | grep -E '^(NAME|PATH)_MAX' NAME_MAX 255 PATH_MAX 4096 I won't change the test script, but it does seem like gnulib's posix_spawnp() could deal with that, especially given that it doesn't apply any NAME_MAX or PATH_MAX limit checks before passing onto execve(). $ PATH=$(printf '%256s' ''):$PATH src/ginstall -s -c -m 555 dd dir ginstall: strip process terminated abnormally With the attached, the problematic path is skipped and strip is run. Note the $NAME_MAX limit is also in glibc's execvp: PATH=$(printf '%256s' ''):$PATH install -s -c -m 555 /bin/ls /tmp install: cannot run 'strip': File name too long I'll send a proposal to glibc to make the same adjustment there. Note ELOOP might also be considered skippable, but the kernel can give that for limits in the shebang resolving, so I thought it best to leave that for now. cheers, Padraig
From 86faf1ebe4c3a6c5f3cf6da971b73a8457f0a640 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email protected]> Date: Sat, 8 Nov 2025 11:04:05 +0000 Subject: [PATCH] posix_spawn-internal: skip $PATH components that are too long * lib/spawni.c (__spawni): Skip path components for which execve returns ENAMETOOLONG. --- ChangeLog | 6 ++++++ lib/spawni.c | 1 + 2 files changed, 7 insertions(+) diff --git a/ChangeLog b/ChangeLog index 5b31898d06..03cd375ec7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2025-11-08 Pádraig Brady <[email protected]> + + posix_spawn-internal: skip $PATH components that are too long + * lib/spawni.c (__spawni): Skip path components for + which execve returns ENAMETOOLONG. + 2025-11-06 Collin Funk <[email protected]> renameat, renameatu: Work around GNU/Hurd bugs. diff --git a/lib/spawni.c b/lib/spawni.c index 3f81d95697..18319dc828 100644 --- a/lib/spawni.c +++ b/lib/spawni.c @@ -1091,6 +1091,7 @@ __spawni (pid_t *pid, const char *file, case ENOENT: case ESTALE: case ENOTDIR: + case ENAMETOOLONG: /* Those errors indicate the file is missing or not executable by us, in which case we want to just try the next path directory. */ -- 2.51.1
