aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-24 22:34:43 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-24 22:34:43 +0000
commit22f741484391c3b2fd94881fd41c8c0df9749e95 (patch)
tree6d8f9ac524cefa7ebb0edeeb5e9545e4ada53e29
parent5a867317bb1cbf36d396d9cdb552212607dcc2b1 (diff)
downloadbusybox-w32-22f741484391c3b2fd94881fd41c8c0df9749e95.tar.gz
busybox-w32-22f741484391c3b2fd94881fd41c8c0df9749e95.tar.bz2
busybox-w32-22f741484391c3b2fd94881fd41c8c0df9749e95.zip
ash: prevent exec NN>&- from closing fd used for script reading
-rw-r--r--shell/ash.c33
-rw-r--r--shell/ash_test/ash-redir/redir4.right1
-rwxr-xr-xshell/ash_test/ash-redir/redir4.tests72
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) 4851enum {
4852 COPYFD_EXACT = (int)~(INT_MAX),
4853 COPYFD_RESTORE = (int)((unsigned)COPYFD_EXACT >> 1),
4854};
4852static int 4855static int
4853copyfd(int from, int to) 4856copyfd(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
2exec 13>&-
3exec 12>&-
4exec 11>&-
5exec 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###############################################################
72echo "OK"