mirror of
https://github.com/sheumann/hush.git
synced 2025-01-22 03:30:37 +00:00
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
This commit is contained in:
parent
0f99d49ae6
commit
6a0ad25061
@ -46,8 +46,11 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
* even if libc receives EBADF on write attempts, it feels determined
|
* even if libc receives EBADF on write attempts, it feels determined
|
||||||
* to output data no matter what. So it will try later,
|
* to output data no matter what. So it will try later,
|
||||||
* and possibly will clobber future output. Not good. */
|
* and possibly will clobber future output. Not good. */
|
||||||
if (dup2(1, 1) != 1)
|
// TODO: check fcntl() & O_ACCMODE == O_WRONLY or O_RDWR?
|
||||||
return -1;
|
if (fcntl(1, F_GETFL) == -1)
|
||||||
|
return 1; /* match coreutils 6.10 (sans error msg to stderr) */
|
||||||
|
//if (dup2(1, 1) != 1) - old way
|
||||||
|
// return 1;
|
||||||
|
|
||||||
arg = *++argv;
|
arg = *++argv;
|
||||||
if (!arg)
|
if (!arg)
|
||||||
@ -58,8 +61,8 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
char eflag = 0;
|
char eflag = 0;
|
||||||
|
|
||||||
/* We must check that stdout is not closed. */
|
/* We must check that stdout is not closed. */
|
||||||
if (dup2(1, 1) != 1)
|
if (fcntl(1, F_GETFL) == -1)
|
||||||
return -1;
|
return 1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
arg = *++argv;
|
arg = *++argv;
|
||||||
|
@ -348,8 +348,11 @@ int printf_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
* even if libc receives EBADF on write attempts, it feels determined
|
* even if libc receives EBADF on write attempts, it feels determined
|
||||||
* to output data no matter what. So it will try later,
|
* to output data no matter what. So it will try later,
|
||||||
* and possibly will clobber future output. Not good. */
|
* and possibly will clobber future output. Not good. */
|
||||||
if (dup2(1, 1) != 1)
|
// TODO: check fcntl() & O_ACCMODE == O_WRONLY or O_RDWR?
|
||||||
return -1;
|
if (fcntl(1, F_GETFL) == -1)
|
||||||
|
return 1; /* match coreutils 6.10 (sans error msg to stderr) */
|
||||||
|
//if (dup2(1, 1) != 1) - old way
|
||||||
|
// return 1;
|
||||||
|
|
||||||
/* bash builtin errors out on "printf '-%s-\n' foo",
|
/* bash builtin errors out on "printf '-%s-\n' foo",
|
||||||
* coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo".
|
* coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo".
|
||||||
|
47
shell/ash.c
47
shell/ash.c
@ -4889,7 +4889,7 @@ static int need_to_remember(struct redirtab *rp, int fd)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!rp) /* remebering was not requested */
|
if (!rp) /* remembering was not requested */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < rp->pair_count; i++) {
|
for (i = 0; i < rp->pair_count; i++) {
|
||||||
@ -4901,6 +4901,28 @@ static int need_to_remember(struct redirtab *rp, int fd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* "hidden" fd is a fd used to read scripts, or a copy of such */
|
||||||
|
static int is_hidden_fd(struct redirtab *rp, int fd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct parsefile *pf = g_parsefile;
|
||||||
|
while (pf) {
|
||||||
|
if (fd == pf->fd) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
pf = pf->prev;
|
||||||
|
}
|
||||||
|
if (!rp)
|
||||||
|
return 0;
|
||||||
|
fd |= COPYFD_RESTORE;
|
||||||
|
for (i = 0; i < rp->pair_count; i++) {
|
||||||
|
if (rp->two_fd[i].copy == fd) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Process a list of redirection commands. If the REDIR_PUSH flag is set,
|
* Process a list of redirection commands. If the REDIR_PUSH flag is set,
|
||||||
* old file descriptors are stashed away so that the redirection can be
|
* old file descriptors are stashed away so that the redirection can be
|
||||||
@ -4950,8 +4972,15 @@ redirect(union node *redir, int flags)
|
|||||||
do {
|
do {
|
||||||
fd = redir->nfile.fd;
|
fd = redir->nfile.fd;
|
||||||
if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
|
if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
|
||||||
if (redir->ndup.dupfd == fd)
|
int right_fd = redir->ndup.dupfd;
|
||||||
continue; /* redirect from/to same file descriptor */
|
/* redirect from/to same file descriptor? */
|
||||||
|
if (right_fd == fd)
|
||||||
|
continue;
|
||||||
|
/* echo >&10 and 10 is a fd opened to the sh script? */
|
||||||
|
if (is_hidden_fd(sv, right_fd)) {
|
||||||
|
errno = EBADF; /* as if it is closed */
|
||||||
|
ash_msg_and_raise_error("%d: %m", right_fd);
|
||||||
|
}
|
||||||
newfd = -1;
|
newfd = -1;
|
||||||
} else {
|
} else {
|
||||||
newfd = openredirect(redir); /* always >= 0 */
|
newfd = openredirect(redir); /* always >= 0 */
|
||||||
@ -4988,14 +5017,8 @@ redirect(union node *redir, int flags)
|
|||||||
/* "exec fd>&-" should not close fds
|
/* "exec fd>&-" should not close fds
|
||||||
* which point to script file(s).
|
* which point to script file(s).
|
||||||
* Force them to be restored afterwards */
|
* Force them to be restored afterwards */
|
||||||
struct parsefile *pf = g_parsefile;
|
if (is_hidden_fd(sv, fd))
|
||||||
while (pf) {
|
i |= COPYFD_RESTORE;
|
||||||
if (fd == pf->fd) {
|
|
||||||
i |= COPYFD_RESTORE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pf = pf->prev;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (fd == 2)
|
if (fd == 2)
|
||||||
copied_fd2 = i;
|
copied_fd2 = i;
|
||||||
@ -9026,7 +9049,7 @@ static int
|
|||||||
preadfd(void)
|
preadfd(void)
|
||||||
{
|
{
|
||||||
int nr;
|
int nr;
|
||||||
char *buf = g_parsefile->buf;
|
char *buf = g_parsefile->buf;
|
||||||
parsenextc = buf;
|
parsenextc = buf;
|
||||||
|
|
||||||
#if ENABLE_FEATURE_EDITING
|
#if ENABLE_FEATURE_EDITING
|
||||||
|
Loading…
x
Reference in New Issue
Block a user