ash: fix open fds leaking in redirects. Closes 9561
commit e19923f665
deleted clearredir()
call in shellexec():
ash: [REDIR] Remove redundant CLOEXEC calls
Upstream commit:
Now that we're marking file descriptors as CLOEXEC in savefd, we no longer
need to close them on exec or in setinputfd.
but it missed one place where we don't set CLOEXEC. Fixing this.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
fe93624fb6
commit
86584e134e
11
shell/ash.c
11
shell/ash.c
@ -5433,11 +5433,11 @@ redirect(union node *redir, int flags)
|
|||||||
/* Careful to not accidentally "save"
|
/* Careful to not accidentally "save"
|
||||||
* to the same fd as right side fd in N>&M */
|
* to the same fd as right side fd in N>&M */
|
||||||
int minfd = right_fd < 10 ? 10 : right_fd + 1;
|
int minfd = right_fd < 10 ? 10 : right_fd + 1;
|
||||||
|
#if defined(F_DUPFD_CLOEXEC)
|
||||||
|
i = fcntl(fd, F_DUPFD_CLOEXEC, minfd);
|
||||||
|
#else
|
||||||
i = fcntl(fd, F_DUPFD, minfd);
|
i = fcntl(fd, F_DUPFD, minfd);
|
||||||
/* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds
|
#endif
|
||||||
* are closed in popredir() in the child, preventing them from leaking
|
|
||||||
* into child. (popredir() also cleans up the mess in case of failures)
|
|
||||||
*/
|
|
||||||
if (i == -1) {
|
if (i == -1) {
|
||||||
i = errno;
|
i = errno;
|
||||||
if (i != EBADF) {
|
if (i != EBADF) {
|
||||||
@ -5452,6 +5452,9 @@ redirect(union node *redir, int flags)
|
|||||||
remember_to_close:
|
remember_to_close:
|
||||||
i = CLOSED;
|
i = CLOSED;
|
||||||
} else { /* fd is open, save its copy */
|
} else { /* fd is open, save its copy */
|
||||||
|
#if !defined(F_DUPFD_CLOEXEC)
|
||||||
|
fcntl(i, F_SETFD, FD_CLOEXEC);
|
||||||
|
#endif
|
||||||
/* "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 */
|
||||||
|
6
shell/ash_test/ash-redir/redir_leak.right
Normal file
6
shell/ash_test/ash-redir/redir_leak.right
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
4
|
||||||
|
4
|
||||||
|
4
|
||||||
|
4
|
||||||
|
4
|
||||||
|
4
|
10
shell/ash_test/ash-redir/redir_leak.tests
Executable file
10
shell/ash_test/ash-redir/redir_leak.tests
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
# Each of these should show only four lines:
|
||||||
|
# fds 0,1,2 are stdio; fd 3 is open by opendir() in ls.
|
||||||
|
# This test detects bugs where redirects leave stray open fds.
|
||||||
|
|
||||||
|
ls -1 /proc/self/fd | wc -l
|
||||||
|
ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l
|
||||||
|
ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l
|
||||||
|
echo "`ls -1 /proc/self/fd `" | wc -l
|
||||||
|
echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l
|
||||||
|
echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l
|
6
shell/hush_test/hush-redir/redir_leak.right
Normal file
6
shell/hush_test/hush-redir/redir_leak.right
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
4
|
||||||
|
4
|
||||||
|
4
|
||||||
|
4
|
||||||
|
4
|
||||||
|
4
|
10
shell/hush_test/hush-redir/redir_leak.tests
Executable file
10
shell/hush_test/hush-redir/redir_leak.tests
Executable file
@ -0,0 +1,10 @@
|
|||||||
|
# Each of these should show only four lines:
|
||||||
|
# fds 0,1,2 are stdio; fd 3 is open by opendir() in ls.
|
||||||
|
# This test detects bugs where redirects leave stray open fds.
|
||||||
|
|
||||||
|
ls -1 /proc/self/fd | wc -l
|
||||||
|
ls -1 /proc/self/fd >/proc/self/fd/1 | wc -l
|
||||||
|
ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 | wc -l
|
||||||
|
echo "`ls -1 /proc/self/fd `" | wc -l
|
||||||
|
echo "`ls -1 /proc/self/fd >/proc/self/fd/1 `" | wc -l
|
||||||
|
echo "`ls -1 /proc/self/fd >/proc/self/fd/1 2>&1 `" | wc -l
|
Loading…
Reference in New Issue
Block a user