ash: fix open fds leaking in redirects. Closes 9561
No binary (build failed)
—
(log yok)
| @@ -5433,11 +5433,11 @@ redirect(union node *redir, int flags) | |
| /* Careful to not accidentally "save" | |
| * to the same fd as right side fd in N>&M */ | |
| int minfd = right_fd < 10 ? 10 : right_fd + 1; | |
| + | #if defined(F_DUPFD_CLOEXEC) |
| + | i = fcntl(fd, F_DUPFD_CLOEXEC, minfd); |
| + | #else |
| i = fcntl(fd, F_DUPFD, minfd); | |
| - | /* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds |
| - | * are closed in popredir() in the child, preventing them from leaking |
| - | * into child. (popredir() also cleans up the mess in case of failures) |
| - | */ |
| + | #endif |
| if (i == -1) { | |
| i = errno; | |
| if (i != EBADF) { | |
| @@ -5452,6 +5452,9 @@ redirect(union node *redir, int flags) | |
| remember_to_close: | |
| i = CLOSED; | |
| } else { /* fd is open, save its copy */ | |
| + | #if !defined(F_DUPFD_CLOEXEC) |
| + | fcntl(i, F_SETFD, FD_CLOEXEC); |
| + | #endif |
| /* "exec fd>&-" should not close fds | |
| * which point to script file(s). | |
| * Force them to be restored afterwards */ | |
| @@ -0,0 +1,6 @@ | |
| + | 4 |
| + | 4 |
| + | 4 |
| + | 4 |
| + | 4 |
| + | 4 |
| @@ -0,0 +1,10 @@ | |
| + | # Each of these should show only four lines: |
| + | # fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. |
| + | # This test detects bugs where redirects leave stray open fds. |
| + | |
| + | ls -1 /proc/self/fd | wc -l |
| + | ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l |
| + | ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l |
| + | echo "`ls -1 /proc/self/fd `" | wc -l |
| + | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l |
| + | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l |
| @@ -0,0 +1,6 @@ | |
| + | 4 |
| + | 4 |
| + | 4 |
| + | 4 |
| + | 4 |
| + | 4 |
| @@ -0,0 +1,10 @@ | |
| + | # Each of these should show only four lines: |
| + | # fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. |
| + | # This test detects bugs where redirects leave stray open fds. |
| + | |
| + | ls -1 /proc/self/fd | wc -l |
| + | ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l |
| + | ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l |
| + | echo "`ls -1 /proc/self/fd `" | wc -l |
| + | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l |
| + | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l |