diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-24 22:34:43 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-24 22:34:43 +0000 |
| commit | 22f741484391c3b2fd94881fd41c8c0df9749e95 (patch) | |
| tree | 6d8f9ac524cefa7ebb0edeeb5e9545e4ada53e29 /shell | |
| parent | 5a867317bb1cbf36d396d9cdb552212607dcc2b1 (diff) | |
| download | busybox-w32-22f741484391c3b2fd94881fd41c8c0df9749e95.tar.gz busybox-w32-22f741484391c3b2fd94881fd41c8c0df9749e95.tar.bz2 busybox-w32-22f741484391c3b2fd94881fd41c8c0df9749e95.zip | |
ash: prevent exec NN>&- from closing fd used for script reading
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 33 | ||||
| -rw-r--r-- | shell/ash_test/ash-redir/redir4.right | 1 | ||||
| -rwxr-xr-x | shell/ash_test/ash-redir/redir4.tests | 72 |
3 files changed, 98 insertions, 8 deletions
diff --git a/shell/ash.c b/shell/ash.c index ec3bd0927..bd2433c88 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -4848,7 +4848,10 @@ openredirect(union node *redir) | |||
| 4848 | */ | 4848 | */ |
| 4849 | /* 0x800..00: bit to set in "to" to request dup2 instead of fcntl(F_DUPFD). | 4849 | /* 0x800..00: bit to set in "to" to request dup2 instead of fcntl(F_DUPFD). |
| 4850 | * old code was doing close(to) prior to copyfd() to achieve the same */ | 4850 | * old code was doing close(to) prior to copyfd() to achieve the same */ |
| 4851 | #define COPYFD_EXACT ((int)~INT_MAX) | 4851 | enum { |
| 4852 | COPYFD_EXACT = (int)~(INT_MAX), | ||
| 4853 | COPYFD_RESTORE = (int)((unsigned)COPYFD_EXACT >> 1), | ||
| 4854 | }; | ||
| 4852 | static int | 4855 | static int |
| 4853 | copyfd(int from, int to) | 4856 | copyfd(int from, int to) |
| 4854 | { | 4857 | { |
| @@ -4981,7 +4984,19 @@ redirect(union node *redir, int flags) | |||
| 4981 | /* EBADF: it is not open - good, remember to close it */ | 4984 | /* EBADF: it is not open - good, remember to close it */ |
| 4982 | remember_to_close: | 4985 | remember_to_close: |
| 4983 | i = CLOSED; | 4986 | i = CLOSED; |
| 4984 | } /* else: fd is open, save its copy */ | 4987 | } else { /* fd is open, save its copy */ |
| 4988 | /* "exec fd>&-" should not close fds | ||
| 4989 | * which point to script file(s). | ||
| 4990 | * Force them to be restored afterwards */ | ||
| 4991 | struct parsefile *pf = g_parsefile; | ||
| 4992 | while (pf) { | ||
| 4993 | if (fd == pf->fd) { | ||
| 4994 | i |= COPYFD_RESTORE; | ||
| 4995 | break; | ||
| 4996 | } | ||
| 4997 | pf = pf->prev; | ||
| 4998 | } | ||
| 4999 | } | ||
| 4985 | if (fd == 2) | 5000 | if (fd == 2) |
| 4986 | copied_fd2 = i; | 5001 | copied_fd2 = i; |
| 4987 | sv->two_fd[sv_pos].orig = fd; | 5002 | sv->two_fd[sv_pos].orig = fd; |
| @@ -4990,7 +5005,7 @@ redirect(union node *redir, int flags) | |||
| 4990 | } | 5005 | } |
| 4991 | if (newfd < 0) { | 5006 | if (newfd < 0) { |
| 4992 | /* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */ | 5007 | /* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */ |
| 4993 | if (redir->ndup.dupfd < 0) { /* "NN>&-" */ | 5008 | if (redir->ndup.dupfd < 0) { /* "fd>&-" */ |
| 4994 | close(fd); | 5009 | close(fd); |
| 4995 | } else { | 5010 | } else { |
| 4996 | copyfd(redir->ndup.dupfd, fd | COPYFD_EXACT); | 5011 | copyfd(redir->ndup.dupfd, fd | COPYFD_EXACT); |
| @@ -5021,17 +5036,19 @@ popredir(int drop) | |||
| 5021 | rp = redirlist; | 5036 | rp = redirlist; |
| 5022 | for (i = 0; i < rp->pair_count; i++) { | 5037 | for (i = 0; i < rp->pair_count; i++) { |
| 5023 | int fd = rp->two_fd[i].orig; | 5038 | int fd = rp->two_fd[i].orig; |
| 5024 | if (rp->two_fd[i].copy == CLOSED) { | 5039 | int copy = rp->two_fd[i].copy; |
| 5040 | if (copy == CLOSED) { | ||
| 5025 | if (!drop) | 5041 | if (!drop) |
| 5026 | close(fd); | 5042 | close(fd); |
| 5027 | continue; | 5043 | continue; |
| 5028 | } | 5044 | } |
| 5029 | if (rp->two_fd[i].copy != EMPTY) { | 5045 | if (copy != EMPTY) { |
| 5030 | if (!drop) { | 5046 | if (!drop || (copy & COPYFD_RESTORE)) { |
| 5047 | copy &= ~COPYFD_RESTORE; | ||
| 5031 | /*close(fd);*/ | 5048 | /*close(fd);*/ |
| 5032 | copyfd(rp->two_fd[i].copy, fd | COPYFD_EXACT); | 5049 | copyfd(copy, fd | COPYFD_EXACT); |
| 5033 | } | 5050 | } |
| 5034 | close(rp->two_fd[i].copy); | 5051 | close(copy); |
| 5035 | } | 5052 | } |
| 5036 | } | 5053 | } |
| 5037 | redirlist = rp->next; | 5054 | redirlist = rp->next; |
diff --git a/shell/ash_test/ash-redir/redir4.right b/shell/ash_test/ash-redir/redir4.right new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/shell/ash_test/ash-redir/redir4.right | |||
| @@ -0,0 +1 @@ | |||
| OK | |||
diff --git a/shell/ash_test/ash-redir/redir4.tests b/shell/ash_test/ash-redir/redir4.tests new file mode 100755 index 000000000..4bdf5ae27 --- /dev/null +++ b/shell/ash_test/ash-redir/redir4.tests | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | # ash uses fd 10 (usually) for reading the script | ||
| 2 | exec 13>&- | ||
| 3 | exec 12>&- | ||
| 4 | exec 11>&- | ||
| 5 | exec 10>&- | ||
| 6 | # some amount of input is prefetched. | ||
| 7 | # make sure final echo is far enough to not be prefetched. | ||
| 8 | ############################################################### | ||
| 9 | ############################################################### | ||
| 10 | ############################################################### | ||
| 11 | ############################################################### | ||
| 12 | ############################################################### | ||
| 13 | ############################################################### | ||
| 14 | ############################################################### | ||
| 15 | ############################################################### | ||
| 16 | ############################################################### | ||
| 17 | ############################################################### | ||
| 18 | ############################################################### | ||
| 19 | ############################################################### | ||
| 20 | ############################################################### | ||
| 21 | ############################################################### | ||
| 22 | ############################################################### | ||
| 23 | ############################################################### | ||
| 24 | ############################################################### | ||
| 25 | ############################################################### | ||
| 26 | ############################################################### | ||
| 27 | ############################################################### | ||
| 28 | ############################################################### | ||
| 29 | ############################################################### | ||
| 30 | ############################################################### | ||
| 31 | ############################################################### | ||
| 32 | ############################################################### | ||
| 33 | ############################################################### | ||
| 34 | ############################################################### | ||
| 35 | ############################################################### | ||
| 36 | ############################################################### | ||
| 37 | ############################################################### | ||
| 38 | ############################################################### | ||
| 39 | ############################################################### | ||
| 40 | ############################################################### | ||
| 41 | ############################################################### | ||
| 42 | ############################################################### | ||
| 43 | ############################################################### | ||
| 44 | ############################################################### | ||
| 45 | ############################################################### | ||
| 46 | ############################################################### | ||
| 47 | ############################################################### | ||
| 48 | ############################################################### | ||
| 49 | ############################################################### | ||
| 50 | ############################################################### | ||
| 51 | ############################################################### | ||
| 52 | ############################################################### | ||
| 53 | ############################################################### | ||
| 54 | ############################################################### | ||
| 55 | ############################################################### | ||
| 56 | ############################################################### | ||
| 57 | ############################################################### | ||
| 58 | ############################################################### | ||
| 59 | ############################################################### | ||
| 60 | ############################################################### | ||
| 61 | ############################################################### | ||
| 62 | ############################################################### | ||
| 63 | ############################################################### | ||
| 64 | ############################################################### | ||
| 65 | ############################################################### | ||
| 66 | ############################################################### | ||
| 67 | ############################################################### | ||
| 68 | ############################################################### | ||
| 69 | ############################################################### | ||
| 70 | ############################################################### | ||
| 71 | ############################################################### | ||
| 72 | echo "OK" | ||
