aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-07 10:15:01 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-10 16:55:51 +0100
commit8e38108d03e0e583eabf61953b5e7b4f5af8966f (patch)
treea60319d70aa9e33f119228354b4ce00fac671e63
parentadd927e3d16414738ce46c28bb9d83e173848740 (diff)
downloadbusybox-w32-8e38108d03e0e583eabf61953b5e7b4f5af8966f.tar.gz
busybox-w32-8e38108d03e0e583eabf61953b5e7b4f5af8966f.tar.bz2
busybox-w32-8e38108d03e0e583eabf61953b5e7b4f5af8966f.zip
ash: fix open fds leaking in redirects. Closes 9561
commit e19923f6652a638ac39c84012e97f52cf5a7568e deleted clearredir() call in shellexec(): ash: [REDIR] Remove redundant CLOEXEC calls Upstream commit: Now that we're marking file descriptors as CLOEXEC in savefd, we no longer need to close them on exec or in setinputfd. but it missed one place where we don't set CLOEXEC. Fixing this. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c11
-rw-r--r--shell/ash_test/ash-redir/redir_leak.right6
-rwxr-xr-xshell/ash_test/ash-redir/redir_leak.tests10
-rw-r--r--shell/hush_test/hush-redir/redir_leak.right6
-rwxr-xr-xshell/hush_test/hush-redir/redir_leak.tests10
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 @@
14
24
34
44
54
64
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
5ls -1 /proc/self/fd | wc -l
6ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l
7ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l
8echo "`ls -1 /proc/self/fd `" | wc -l
9echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l
10echo "`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 @@
14
24
34
44
54
64
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
5ls -1 /proc/self/fd | wc -l
6ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l
7ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l
8echo "`ls -1 /proc/self/fd `" | wc -l
9echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l
10echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l