diff options
-rw-r--r-- | shell/ash.c | 11 | ||||
-rw-r--r-- | shell/ash_test/ash-redir/redir_leak.right | 6 | ||||
-rwxr-xr-x | shell/ash_test/ash-redir/redir_leak.tests | 10 | ||||
-rw-r--r-- | shell/hush_test/hush-redir/redir_leak.right | 6 | ||||
-rwxr-xr-x | shell/hush_test/hush-redir/redir_leak.tests | 10 |
5 files changed, 39 insertions, 4 deletions
diff --git a/shell/ash.c b/shell/ash.c index 7c53946ce..e6d02f69c 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -5426,11 +5426,11 @@ redirect(union node *redir, int flags) | |||
5426 | /* Careful to not accidentally "save" | 5426 | /* Careful to not accidentally "save" |
5427 | * to the same fd as right side fd in N>&M */ | 5427 | * to the same fd as right side fd in N>&M */ |
5428 | int minfd = right_fd < 10 ? 10 : right_fd + 1; | 5428 | int minfd = right_fd < 10 ? 10 : right_fd + 1; |
5429 | #if defined(F_DUPFD_CLOEXEC) | ||
5430 | i = fcntl(fd, F_DUPFD_CLOEXEC, minfd); | ||
5431 | #else | ||
5429 | i = fcntl(fd, F_DUPFD, minfd); | 5432 | i = fcntl(fd, F_DUPFD, minfd); |
5430 | /* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds | 5433 | #endif |
5431 | * are closed in popredir() in the child, preventing them from leaking | ||
5432 | * into child. (popredir() also cleans up the mess in case of failures) | ||
5433 | */ | ||
5434 | if (i == -1) { | 5434 | if (i == -1) { |
5435 | i = errno; | 5435 | i = errno; |
5436 | if (i != EBADF) { | 5436 | if (i != EBADF) { |
@@ -5445,6 +5445,9 @@ redirect(union node *redir, int flags) | |||
5445 | remember_to_close: | 5445 | remember_to_close: |
5446 | i = CLOSED; | 5446 | i = CLOSED; |
5447 | } else { /* fd is open, save its copy */ | 5447 | } else { /* fd is open, save its copy */ |
5448 | #if !defined(F_DUPFD_CLOEXEC) | ||
5449 | fcntl(i, F_SETFD, FD_CLOEXEC); | ||
5450 | #endif | ||
5448 | /* "exec fd>&-" should not close fds | 5451 | /* "exec fd>&-" should not close fds |
5449 | * which point to script file(s). | 5452 | * which point to script file(s). |
5450 | * Force them to be restored afterwards */ | 5453 | * Force them to be restored afterwards */ |
diff --git a/shell/ash_test/ash-redir/redir_leak.right b/shell/ash_test/ash-redir/redir_leak.right new file mode 100644 index 000000000..b1c48292b --- /dev/null +++ b/shell/ash_test/ash-redir/redir_leak.right | |||
@@ -0,0 +1,6 @@ | |||
1 | 4 | ||
2 | 4 | ||
3 | 4 | ||
4 | 4 | ||
5 | 4 | ||
6 | 4 | ||
diff --git a/shell/ash_test/ash-redir/redir_leak.tests b/shell/ash_test/ash-redir/redir_leak.tests new file mode 100755 index 000000000..c8a9c6343 --- /dev/null +++ b/shell/ash_test/ash-redir/redir_leak.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | # Each of these should show only four lines: | ||
2 | # fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. | ||
3 | # This test detects bugs where redirects leave stray open fds. | ||
4 | |||
5 | ls -1 /proc/self/fd | wc -l | ||
6 | ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l | ||
7 | ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l | ||
8 | echo "`ls -1 /proc/self/fd `" | wc -l | ||
9 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l | ||
10 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l | ||
diff --git a/shell/hush_test/hush-redir/redir_leak.right b/shell/hush_test/hush-redir/redir_leak.right new file mode 100644 index 000000000..b1c48292b --- /dev/null +++ b/shell/hush_test/hush-redir/redir_leak.right | |||
@@ -0,0 +1,6 @@ | |||
1 | 4 | ||
2 | 4 | ||
3 | 4 | ||
4 | 4 | ||
5 | 4 | ||
6 | 4 | ||
diff --git a/shell/hush_test/hush-redir/redir_leak.tests b/shell/hush_test/hush-redir/redir_leak.tests new file mode 100755 index 000000000..c8a9c6343 --- /dev/null +++ b/shell/hush_test/hush-redir/redir_leak.tests | |||
@@ -0,0 +1,10 @@ | |||
1 | # Each of these should show only four lines: | ||
2 | # fds 0,1,2 are stdio; fd 3 is open by opendir() in ls. | ||
3 | # This test detects bugs where redirects leave stray open fds. | ||
4 | |||
5 | ls -1 /proc/self/fd | wc -l | ||
6 | ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l | ||
7 | ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l | ||
8 | echo "`ls -1 /proc/self/fd `" | wc -l | ||
9 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l | ||
10 | echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l | ||