ash: prevent exec NN>&- from closing fd used for script reading

This commit is contained in:
Denis Vlasenko 2008-07-24 22:34:43 +00:00
parent 5a867317bb
commit 22f7414843
3 changed files with 98 additions and 8 deletions

View File

@ -4848,7 +4848,10 @@ openredirect(union node *redir)
*/
/* 0x800..00: bit to set in "to" to request dup2 instead of fcntl(F_DUPFD).
* old code was doing close(to) prior to copyfd() to achieve the same */
#define COPYFD_EXACT ((int)~INT_MAX)
enum {
COPYFD_EXACT = (int)~(INT_MAX),
COPYFD_RESTORE = (int)((unsigned)COPYFD_EXACT >> 1),
};
static int
copyfd(int from, int to)
{
@ -4981,7 +4984,19 @@ redirect(union node *redir, int flags)
/* EBADF: it is not open - good, remember to close it */
remember_to_close:
i = CLOSED;
} /* else: fd is open, save its copy */
} else { /* fd is open, save its copy */
/* "exec fd>&-" should not close fds
* which point to script file(s).
* Force them to be restored afterwards */
struct parsefile *pf = g_parsefile;
while (pf) {
if (fd == pf->fd) {
i |= COPYFD_RESTORE;
break;
}
pf = pf->prev;
}
}
if (fd == 2)
copied_fd2 = i;
sv->two_fd[sv_pos].orig = fd;
@ -4990,7 +5005,7 @@ redirect(union node *redir, int flags)
}
if (newfd < 0) {
/* NTOFD/NFROMFD: copy redir->ndup.dupfd to fd */
if (redir->ndup.dupfd < 0) { /* "NN>&-" */
if (redir->ndup.dupfd < 0) { /* "fd>&-" */
close(fd);
} else {
copyfd(redir->ndup.dupfd, fd | COPYFD_EXACT);
@ -5021,17 +5036,19 @@ popredir(int drop)
rp = redirlist;
for (i = 0; i < rp->pair_count; i++) {
int fd = rp->two_fd[i].orig;
if (rp->two_fd[i].copy == CLOSED) {
int copy = rp->two_fd[i].copy;
if (copy == CLOSED) {
if (!drop)
close(fd);
continue;
}
if (rp->two_fd[i].copy != EMPTY) {
if (!drop) {
if (copy != EMPTY) {
if (!drop || (copy & COPYFD_RESTORE)) {
copy &= ~COPYFD_RESTORE;
/*close(fd);*/
copyfd(rp->two_fd[i].copy, fd | COPYFD_EXACT);
copyfd(copy, fd | COPYFD_EXACT);
}
close(rp->two_fd[i].copy);
close(copy);
}
}
redirlist = rp->next;

View File

@ -0,0 +1 @@
OK

View File

@ -0,0 +1,72 @@
# ash uses fd 10 (usually) for reading the script
exec 13>&-
exec 12>&-
exec 11>&-
exec 10>&-
# some amount of input is prefetched.
# make sure final echo is far enough to not be prefetched.
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
###############################################################
echo "OK"