aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash.c16
-rw-r--r--shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_1.right5
-rwxr-xr-xshell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_1.tests6
-rw-r--r--shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_2.right5
-rwxr-xr-xshell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_2.tests6
-rw-r--r--shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_3.right5
-rwxr-xr-xshell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_3.tests6
-rw-r--r--shell/hush.c23
-rw-r--r--shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_1.right5
-rwxr-xr-xshell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_1.tests6
-rw-r--r--shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_2.right5
-rwxr-xr-xshell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_2.tests6
-rw-r--r--shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_3.right5
-rwxr-xr-xshell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_3.tests6
14 files changed, 92 insertions, 13 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 5e281b5ce..85690e555 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -255,6 +255,9 @@ typedef long arith_t;
255# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__ 255# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
256#endif 256#endif
257 257
258#ifndef F_DUPFD_CLOEXEC
259# define F_DUPFD_CLOEXEC F_DUPFD
260#endif
258#ifndef PIPE_BUF 261#ifndef PIPE_BUF
259# define PIPE_BUF 4096 /* amount of buffering in a pipe */ 262# define PIPE_BUF 4096 /* amount of buffering in a pipe */
260#endif 263#endif
@@ -5448,12 +5451,15 @@ dup2_or_raise(int from, int to)
5448 return newfd; 5451 return newfd;
5449} 5452}
5450static int 5453static int
5451fcntl_F_DUPFD(int fd, int avoid_fd) 5454dup_CLOEXEC(int fd, int avoid_fd)
5452{ 5455{
5453 int newfd; 5456 int newfd;
5454 repeat: 5457 repeat:
5455 newfd = fcntl(fd, F_DUPFD, avoid_fd + 1); 5458 newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
5456 if (newfd < 0) { 5459 if (newfd >= 0) {
5460 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
5461 fcntl(newfd, F_SETFD, FD_CLOEXEC);
5462 } else { /* newfd < 0 */
5457 if (errno == EBUSY) 5463 if (errno == EBUSY)
5458 goto repeat; 5464 goto repeat;
5459 if (errno == EINTR) 5465 if (errno == EINTR)
@@ -5569,7 +5575,7 @@ save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5569 for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) { 5575 for (i = 0; sq->two_fd[i].orig_fd != EMPTY; i++) {
5570 /* If we collide with an already moved fd... */ 5576 /* If we collide with an already moved fd... */
5571 if (fd == sq->two_fd[i].moved_to) { 5577 if (fd == sq->two_fd[i].moved_to) {
5572 new_fd = fcntl_F_DUPFD(fd, avoid_fd); 5578 new_fd = dup_CLOEXEC(fd, avoid_fd);
5573 sq->two_fd[i].moved_to = new_fd; 5579 sq->two_fd[i].moved_to = new_fd;
5574 TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd)); 5580 TRACE(("redirect_fd %d: already busy, moving to %d\n", fd, new_fd));
5575 if (new_fd < 0) /* what? */ 5581 if (new_fd < 0) /* what? */
@@ -5584,7 +5590,7 @@ save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq)
5584 } 5590 }
5585 5591
5586 /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */ 5592 /* If this fd is open, we move and remember it; if it's closed, new_fd = CLOSED (-1) */
5587 new_fd = fcntl_F_DUPFD(fd, avoid_fd); 5593 new_fd = dup_CLOEXEC(fd, avoid_fd);
5588 TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd)); 5594 TRACE(("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, new_fd));
5589 if (new_fd < 0) { 5595 if (new_fd < 0) {
5590 if (errno != EBADF) 5596 if (errno != EBADF)
diff --git a/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_1.right b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_1.right
new file mode 100644
index 000000000..46ab7f5d1
--- /dev/null
+++ b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_1.right
@@ -0,0 +1,5 @@
1/proc/self/fd
2/proc/self/fd/0
3/proc/self/fd/1
4/proc/self/fd/2
5/proc/self/fd/3
diff --git a/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_1.tests b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_1.tests
new file mode 100755
index 000000000..544c810e3
--- /dev/null
+++ b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_1.tests
@@ -0,0 +1,6 @@
1# The "find" should not see "saved" (duplicated) fd #1
2# Explicitly use bbox find, since other implementations of "find"
3# may open other descriptors as well.
4busybox find /proc/self/fd >tmp_$$.out
5cat tmp_$$.out
6rm -f tmp_$$.out
diff --git a/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_2.right b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_2.right
new file mode 100644
index 000000000..46ab7f5d1
--- /dev/null
+++ b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_2.right
@@ -0,0 +1,5 @@
1/proc/self/fd
2/proc/self/fd/0
3/proc/self/fd/1
4/proc/self/fd/2
5/proc/self/fd/3
diff --git a/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_2.tests b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_2.tests
new file mode 100755
index 000000000..43777cade
--- /dev/null
+++ b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_2.tests
@@ -0,0 +1,6 @@
1# The "find" should not see "saved" (duplicated) fd #1
2# Explicitly use bbox find, since other implementations of "find"
3# may open other descriptors as well.
4{ busybox find /proc/self/fd; } >tmp_$$.out
5cat tmp_$$.out
6rm -f tmp_$$.out
diff --git a/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_3.right b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_3.right
new file mode 100644
index 000000000..46ab7f5d1
--- /dev/null
+++ b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_3.right
@@ -0,0 +1,5 @@
1/proc/self/fd
2/proc/self/fd/0
3/proc/self/fd/1
4/proc/self/fd/2
5/proc/self/fd/3
diff --git a/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_3.tests b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_3.tests
new file mode 100755
index 000000000..0a21173bd
--- /dev/null
+++ b/shell/ash_test/ash-redir/redir_children_should_not_see_saved_fd_3.tests
@@ -0,0 +1,6 @@
1# The "find" should not see "saved" (duplicated) fd #1
2# Explicitly use bbox find, since other implementations of "find"
3# may open other descriptors as well.
4{ busybox find /proc/self/fd; true; } >tmp_$$.out
5cat tmp_$$.out
6rm -f tmp_$$.out
diff --git a/shell/hush.c b/shell/hush.c
index 6e64efb70..012ec219f 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1501,12 +1501,15 @@ static void free_strings(char **strings)
1501 free(strings); 1501 free(strings);
1502} 1502}
1503 1503
1504static int fcntl_F_DUPFD(int fd, int avoid_fd) 1504static int dup_CLOEXEC(int fd, int avoid_fd)
1505{ 1505{
1506 int newfd; 1506 int newfd;
1507 repeat: 1507 repeat:
1508 newfd = fcntl(fd, F_DUPFD, avoid_fd + 1); 1508 newfd = fcntl(fd, F_DUPFD_CLOEXEC, avoid_fd + 1);
1509 if (newfd < 0) { 1509 if (newfd >= 0) {
1510 if (F_DUPFD_CLOEXEC == F_DUPFD) /* if old libc (w/o F_DUPFD_CLOEXEC) */
1511 fcntl(newfd, F_SETFD, FD_CLOEXEC);
1512 } else { /* newfd < 0 */
1510 if (errno == EBUSY) 1513 if (errno == EBUSY)
1511 goto repeat; 1514 goto repeat;
1512 if (errno == EINTR) 1515 if (errno == EINTR)
@@ -6890,7 +6893,7 @@ static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
6890 if (sq) for (; sq[i].orig_fd >= 0; i++) { 6893 if (sq) for (; sq[i].orig_fd >= 0; i++) {
6891 /* If we collide with an already moved fd... */ 6894 /* If we collide with an already moved fd... */
6892 if (fd == sq[i].moved_to) { 6895 if (fd == sq[i].moved_to) {
6893 sq[i].moved_to = fcntl_F_DUPFD(sq[i].moved_to, avoid_fd); 6896 sq[i].moved_to = dup_CLOEXEC(sq[i].moved_to, avoid_fd);
6894 debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, sq[i].moved_to); 6897 debug_printf_redir("redirect_fd %d: already busy, moving to %d\n", fd, sq[i].moved_to);
6895 if (sq[i].moved_to < 0) /* what? */ 6898 if (sq[i].moved_to < 0) /* what? */
6896 xfunc_die(); 6899 xfunc_die();
@@ -6904,7 +6907,7 @@ static struct squirrel *add_squirrel(struct squirrel *sq, int fd, int avoid_fd)
6904 } 6907 }
6905 6908
6906 /* If this fd is open, we move and remember it; if it's closed, moved_to = -1 */ 6909 /* If this fd is open, we move and remember it; if it's closed, moved_to = -1 */
6907 moved_to = fcntl_F_DUPFD(fd, avoid_fd); 6910 moved_to = dup_CLOEXEC(fd, avoid_fd);
6908 debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to); 6911 debug_printf_redir("redirect_fd %d: previous fd is moved to %d (-1 if it was closed)\n", fd, moved_to);
6909 if (moved_to < 0 && errno != EBADF) 6912 if (moved_to < 0 && errno != EBADF)
6910 xfunc_die(); 6913 xfunc_die();
@@ -7622,6 +7625,10 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save,
7622 */ 7625 */
7623 close_saved_fds_and_FILE_fds(); 7626 close_saved_fds_and_FILE_fds();
7624//FIXME: should also close saved redir fds 7627//FIXME: should also close saved redir fds
7628//This casuses test failures in
7629//redir_children_should_not_see_saved_fd_2.tests
7630//redir_children_should_not_see_saved_fd_3.tests
7631//if you replace "busybox find" with just "find" in them
7625 /* Without this, "rm -i FILE" can't be ^C'ed: */ 7632 /* Without this, "rm -i FILE" can't be ^C'ed: */
7626 switch_off_special_sigs(G.special_sig_mask); 7633 switch_off_special_sigs(G.special_sig_mask);
7627 debug_printf_exec("running applet '%s'\n", argv[0]); 7634 debug_printf_exec("running applet '%s'\n", argv[0]);
@@ -9347,7 +9354,7 @@ int hush_main(int argc, char **argv)
9347 G_saved_tty_pgrp = 0; 9354 G_saved_tty_pgrp = 0;
9348 9355
9349 /* try to dup stdin to high fd#, >= 255 */ 9356 /* try to dup stdin to high fd#, >= 255 */
9350 G_interactive_fd = fcntl_F_DUPFD(STDIN_FILENO, 254); 9357 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
9351 if (G_interactive_fd < 0) { 9358 if (G_interactive_fd < 0) {
9352 /* try to dup to any fd */ 9359 /* try to dup to any fd */
9353 G_interactive_fd = dup(STDIN_FILENO); 9360 G_interactive_fd = dup(STDIN_FILENO);
@@ -9420,10 +9427,10 @@ int hush_main(int argc, char **argv)
9420#elif ENABLE_HUSH_INTERACTIVE 9427#elif ENABLE_HUSH_INTERACTIVE
9421 /* No job control compiled in, only prompt/line editing */ 9428 /* No job control compiled in, only prompt/line editing */
9422 if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { 9429 if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) {
9423 G_interactive_fd = fcntl_F_DUPFD(STDIN_FILENO, 254); 9430 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO, 254);
9424 if (G_interactive_fd < 0) { 9431 if (G_interactive_fd < 0) {
9425 /* try to dup to any fd */ 9432 /* try to dup to any fd */
9426 G_interactive_fd = dup(STDIN_FILENO); 9433 G_interactive_fd = dup_CLOEXEC(STDIN_FILENO);
9427 if (G_interactive_fd < 0) 9434 if (G_interactive_fd < 0)
9428 /* give up */ 9435 /* give up */
9429 G_interactive_fd = 0; 9436 G_interactive_fd = 0;
diff --git a/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_1.right b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_1.right
new file mode 100644
index 000000000..46ab7f5d1
--- /dev/null
+++ b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_1.right
@@ -0,0 +1,5 @@
1/proc/self/fd
2/proc/self/fd/0
3/proc/self/fd/1
4/proc/self/fd/2
5/proc/self/fd/3
diff --git a/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_1.tests b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_1.tests
new file mode 100755
index 000000000..544c810e3
--- /dev/null
+++ b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_1.tests
@@ -0,0 +1,6 @@
1# The "find" should not see "saved" (duplicated) fd #1
2# Explicitly use bbox find, since other implementations of "find"
3# may open other descriptors as well.
4busybox find /proc/self/fd >tmp_$$.out
5cat tmp_$$.out
6rm -f tmp_$$.out
diff --git a/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_2.right b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_2.right
new file mode 100644
index 000000000..46ab7f5d1
--- /dev/null
+++ b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_2.right
@@ -0,0 +1,5 @@
1/proc/self/fd
2/proc/self/fd/0
3/proc/self/fd/1
4/proc/self/fd/2
5/proc/self/fd/3
diff --git a/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_2.tests b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_2.tests
new file mode 100755
index 000000000..43777cade
--- /dev/null
+++ b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_2.tests
@@ -0,0 +1,6 @@
1# The "find" should not see "saved" (duplicated) fd #1
2# Explicitly use bbox find, since other implementations of "find"
3# may open other descriptors as well.
4{ busybox find /proc/self/fd; } >tmp_$$.out
5cat tmp_$$.out
6rm -f tmp_$$.out
diff --git a/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_3.right b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_3.right
new file mode 100644
index 000000000..46ab7f5d1
--- /dev/null
+++ b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_3.right
@@ -0,0 +1,5 @@
1/proc/self/fd
2/proc/self/fd/0
3/proc/self/fd/1
4/proc/self/fd/2
5/proc/self/fd/3
diff --git a/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_3.tests b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_3.tests
new file mode 100755
index 000000000..0a21173bd
--- /dev/null
+++ b/shell/hush_test/hush-redir/redir_children_should_not_see_saved_fd_3.tests
@@ -0,0 +1,6 @@
1# The "find" should not see "saved" (duplicated) fd #1
2# Explicitly use bbox find, since other implementations of "find"
3# may open other descriptors as well.
4{ busybox find /proc/self/fd; true; } >tmp_$$.out
5cat tmp_$$.out
6rm -f tmp_$$.out