aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-25 13:34:05 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-25 13:34:05 +0000
commit6a0ad2506116f4ddc3f9f617a90ba04a57eeef88 (patch)
treebb40f8aa8574d4aef536cfe930517c0bf44e28a7
parent0f99d49ae680e675809428deace3c4fe839d323c (diff)
downloadbusybox-w32-6a0ad2506116f4ddc3f9f617a90ba04a57eeef88.tar.gz
busybox-w32-6a0ad2506116f4ddc3f9f617a90ba04a57eeef88.tar.bz2
busybox-w32-6a0ad2506116f4ddc3f9f617a90ba04a57eeef88.zip
ash: dont allow e.g. exec <&10 to attach to stript's fd!
function old new delta is_hidden_fd - 61 +61 redirect 1135 1164 +29 popstring 134 140 +6 printf_main 635 637 +2 evalvar 1374 1376 +2 echo_main 294 296 +2 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 5/0 up/down: 102/0) Total: 102 bytes
-rw-r--r--coreutils/echo.c11
-rw-r--r--coreutils/printf.c7
-rw-r--r--shell/ash.c47
3 files changed, 47 insertions, 18 deletions
diff --git a/coreutils/echo.c b/coreutils/echo.c
index 36cb6b3af..decca095f 100644
--- a/coreutils/echo.c
+++ b/coreutils/echo.c
@@ -46,8 +46,11 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
46 * even if libc receives EBADF on write attempts, it feels determined 46 * even if libc receives EBADF on write attempts, it feels determined
47 * to output data no matter what. So it will try later, 47 * to output data no matter what. So it will try later,
48 * and possibly will clobber future output. Not good. */ 48 * and possibly will clobber future output. Not good. */
49 if (dup2(1, 1) != 1) 49// TODO: check fcntl() & O_ACCMODE == O_WRONLY or O_RDWR?
50 return -1; 50 if (fcntl(1, F_GETFL) == -1)
51 return 1; /* match coreutils 6.10 (sans error msg to stderr) */
52 //if (dup2(1, 1) != 1) - old way
53 // return 1;
51 54
52 arg = *++argv; 55 arg = *++argv;
53 if (!arg) 56 if (!arg)
@@ -58,8 +61,8 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
58 char eflag = 0; 61 char eflag = 0;
59 62
60 /* We must check that stdout is not closed. */ 63 /* We must check that stdout is not closed. */
61 if (dup2(1, 1) != 1) 64 if (fcntl(1, F_GETFL) == -1)
62 return -1; 65 return 1;
63 66
64 while (1) { 67 while (1) {
65 arg = *++argv; 68 arg = *++argv;
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 72acbc751..76524f706 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -348,8 +348,11 @@ int printf_main(int argc UNUSED_PARAM, char **argv)
348 * even if libc receives EBADF on write attempts, it feels determined 348 * even if libc receives EBADF on write attempts, it feels determined
349 * to output data no matter what. So it will try later, 349 * to output data no matter what. So it will try later,
350 * and possibly will clobber future output. Not good. */ 350 * and possibly will clobber future output. Not good. */
351 if (dup2(1, 1) != 1) 351// TODO: check fcntl() & O_ACCMODE == O_WRONLY or O_RDWR?
352 return -1; 352 if (fcntl(1, F_GETFL) == -1)
353 return 1; /* match coreutils 6.10 (sans error msg to stderr) */
354 //if (dup2(1, 1) != 1) - old way
355 // return 1;
353 356
354 /* bash builtin errors out on "printf '-%s-\n' foo", 357 /* bash builtin errors out on "printf '-%s-\n' foo",
355 * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo". 358 * coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo".
diff --git a/shell/ash.c b/shell/ash.c
index bd2433c88..11174683e 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -4889,7 +4889,7 @@ static int need_to_remember(struct redirtab *rp, int fd)
4889{ 4889{
4890 int i; 4890 int i;
4891 4891
4892 if (!rp) /* remebering was not requested */ 4892 if (!rp) /* remembering was not requested */
4893 return 0; 4893 return 0;
4894 4894
4895 for (i = 0; i < rp->pair_count; i++) { 4895 for (i = 0; i < rp->pair_count; i++) {
@@ -4901,6 +4901,28 @@ static int need_to_remember(struct redirtab *rp, int fd)
4901 return 1; 4901 return 1;
4902} 4902}
4903 4903
4904/* "hidden" fd is a fd used to read scripts, or a copy of such */
4905static int is_hidden_fd(struct redirtab *rp, int fd)
4906{
4907 int i;
4908 struct parsefile *pf = g_parsefile;
4909 while (pf) {
4910 if (fd == pf->fd) {
4911 return 1;
4912 }
4913 pf = pf->prev;
4914 }
4915 if (!rp)
4916 return 0;
4917 fd |= COPYFD_RESTORE;
4918 for (i = 0; i < rp->pair_count; i++) {
4919 if (rp->two_fd[i].copy == fd) {
4920 return 1;
4921 }
4922 }
4923 return 0;
4924}
4925
4904/* 4926/*
4905 * Process a list of redirection commands. If the REDIR_PUSH flag is set, 4927 * Process a list of redirection commands. If the REDIR_PUSH flag is set,
4906 * old file descriptors are stashed away so that the redirection can be 4928 * old file descriptors are stashed away so that the redirection can be
@@ -4950,8 +4972,15 @@ redirect(union node *redir, int flags)
4950 do { 4972 do {
4951 fd = redir->nfile.fd; 4973 fd = redir->nfile.fd;
4952 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { 4974 if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
4953 if (redir->ndup.dupfd == fd) 4975 int right_fd = redir->ndup.dupfd;
4954 continue; /* redirect from/to same file descriptor */ 4976 /* redirect from/to same file descriptor? */
4977 if (right_fd == fd)
4978 continue;
4979 /* echo >&10 and 10 is a fd opened to the sh script? */
4980 if (is_hidden_fd(sv, right_fd)) {
4981 errno = EBADF; /* as if it is closed */
4982 ash_msg_and_raise_error("%d: %m", right_fd);
4983 }
4955 newfd = -1; 4984 newfd = -1;
4956 } else { 4985 } else {
4957 newfd = openredirect(redir); /* always >= 0 */ 4986 newfd = openredirect(redir); /* always >= 0 */
@@ -4988,14 +5017,8 @@ redirect(union node *redir, int flags)
4988 /* "exec fd>&-" should not close fds 5017 /* "exec fd>&-" should not close fds
4989 * which point to script file(s). 5018 * which point to script file(s).
4990 * Force them to be restored afterwards */ 5019 * Force them to be restored afterwards */
4991 struct parsefile *pf = g_parsefile; 5020 if (is_hidden_fd(sv, fd))
4992 while (pf) { 5021 i |= COPYFD_RESTORE;
4993 if (fd == pf->fd) {
4994 i |= COPYFD_RESTORE;
4995 break;
4996 }
4997 pf = pf->prev;
4998 }
4999 } 5022 }
5000 if (fd == 2) 5023 if (fd == 2)
5001 copied_fd2 = i; 5024 copied_fd2 = i;
@@ -9026,7 +9049,7 @@ static int
9026preadfd(void) 9049preadfd(void)
9027{ 9050{
9028 int nr; 9051 int nr;
9029 char *buf = g_parsefile->buf; 9052 char *buf = g_parsefile->buf;
9030 parsenextc = buf; 9053 parsenextc = buf;
9031 9054
9032#if ENABLE_FEATURE_EDITING 9055#if ENABLE_FEATURE_EDITING