← Commit list

86584e134

Denys Vlasenko
Denys Vlasenko
2017-01-07
SUCCESS Duration: 230s

Subject

ash: fix open fds leaking in redirects. Closes 9561

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

shell/ash.c+7 -4
@@ -5433,11 +5433,11 @@ redirect(union node *redir, int flags)
/* Careful to not accidentally "save"
* to the same fd as right side fd in N>&M */
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);
-/* You'd expect copy to be CLOEXECed. Currently these extra "saved" fds
- * are closed in popredir() in the child, preventing them from leaking
- * into child. (popredir() also cleans up the mess in case of failures)
- */
+#endif
if (i == -1) {
i = errno;
if (i != EBADF) {
@@ -5452,6 +5452,9 @@ redirect(union node *redir, int flags)
remember_to_close:
i = CLOSED;
} 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
* which point to script file(s).
* Force them to be restored afterwards */
shell/ash_test/ash-redir/redir_leak.right+6 -0
@@ -0,0 +1,6 @@
+4
+4
+4
+4
+4
+4
shell/ash_test/ash-redir/redir_leak.tests+10 -0
@@ -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
shell/hush_test/hush-redir/redir_leak.right+6 -0
@@ -0,0 +1,6 @@
+4
+4
+4
+4
+4
+4
shell/hush_test/hush-redir/redir_leak.tests+10 -0
@@ -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