diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-31 04:32:06 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-31 04:35:18 +0200 |
commit | 32fdf2f9fc9a617918672d71579f4ad42eb9bde9 (patch) | |
tree | f73fbaa257aeb6810557fe7a36ae6b4b3dfb72e4 /shell/ash.c | |
parent | 035486c7500c09616a6c1040d8e70923532a5c2d (diff) | |
download | busybox-w32-32fdf2f9fc9a617918672d71579f4ad42eb9bde9.tar.gz busybox-w32-32fdf2f9fc9a617918672d71579f4ad42eb9bde9.tar.bz2 busybox-w32-32fdf2f9fc9a617918672d71579f4ad42eb9bde9.zip |
ash,hush: ">&10" redirects to script/tty fds should not work
The fact that shell has open fds to tty and/or scripts should be
unobservable, if possible. In particular, if redirect tries to dup
one of them via ">&script_fd", it's better to pretend that script_fd
is closed, and thus redirect fails with EBADF.
Fixes these two testcase failures:
ash-redir/redir_to_bad_fd.tests
hush-redir/redir_to_bad_fd3.tests
function old new delta
redirect 1018 1129 +111
setup_redirects 250 359 +109
readtoken1 2651 2655 +4
cmdloop 185 187 +2
changepath 194 195 +1
save_fd_on_redirect 203 194 -9
evaltree 501 484 -17
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 5/2 up/down: 227/-26) Total: 201 bytes
text data bss dec hex filename
914553 485 6848 921886 e111e busybox_old
914754 485 6848 922087 e11e7 busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/ash.c')
-rw-r--r-- | shell/ash.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/shell/ash.c b/shell/ash.c index ac676c2dc..5c2e06599 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -5503,6 +5503,31 @@ save_fd_on_redirect(int fd, int avoid_fd, struct redirtab *sq) | |||
5503 | return 0; /* "we did not close fd" */ | 5503 | return 0; /* "we did not close fd" */ |
5504 | } | 5504 | } |
5505 | 5505 | ||
5506 | static int | ||
5507 | internally_opened_fd(int fd, struct redirtab *sq) | ||
5508 | { | ||
5509 | int i; | ||
5510 | #if JOBS | ||
5511 | if (fd == ttyfd) | ||
5512 | return 1; | ||
5513 | #endif | ||
5514 | /* If this one of script's fds? */ | ||
5515 | if (fd != 0) { | ||
5516 | struct parsefile *pf = g_parsefile; | ||
5517 | while (pf) { | ||
5518 | if (fd == pf->pf_fd) | ||
5519 | return 1; | ||
5520 | pf = pf->prev; | ||
5521 | } | ||
5522 | } | ||
5523 | |||
5524 | if (sq) for (i = 0; i < sq->pair_count && sq->two_fd[i].orig_fd != EMPTY; i++) { | ||
5525 | if (fd == sq->two_fd[i].moved_to) | ||
5526 | return 1; | ||
5527 | } | ||
5528 | return 0; | ||
5529 | } | ||
5530 | |||
5506 | /* | 5531 | /* |
5507 | * Process a list of redirection commands. If the REDIR_PUSH flag is set, | 5532 | * Process a list of redirection commands. If the REDIR_PUSH flag is set, |
5508 | * old file descriptors are stashed away so that the redirection can be | 5533 | * old file descriptors are stashed away so that the redirection can be |
@@ -5567,15 +5592,11 @@ redirect(union node *redir, int flags) | |||
5567 | close(fd); | 5592 | close(fd); |
5568 | } | 5593 | } |
5569 | } else { | 5594 | } else { |
5570 | ///TODO: if _newfd_ is a script fd or saved fd, then simulate EBADF! | 5595 | /* if newfd is a script fd or saved fd, simulate EBADF */ |
5571 | //if (newfd == ttyfd) { | 5596 | if (internally_opened_fd(newfd, sv)) { |
5572 | // errno = EBADF; | 5597 | errno = EBADF; |
5573 | // ash_msg_and_raise_perror("A %d", newfd); | 5598 | ash_msg_and_raise_perror("%d", newfd); |
5574 | //} | 5599 | } |
5575 | //if (newfd == g_parsefile->pf_fd) { | ||
5576 | // errno = EBADF; | ||
5577 | // ash_msg_and_raise_perror("B %d", newfd); | ||
5578 | //} | ||
5579 | dup2_or_raise(newfd, fd); | 5600 | dup2_or_raise(newfd, fd); |
5580 | if (close_fd >= 0) /* "N>FILE" or ">&FILE" or heredoc? */ | 5601 | if (close_fd >= 0) /* "N>FILE" or ">&FILE" or heredoc? */ |
5581 | close(close_fd); | 5602 | close(close_fd); |