diff options
author | James Youngman <jay@gnu.org> | 2015-12-23 22:45:18 +0000 |
---|---|---|
committer | James Youngman <jay@gnu.org> | 2015-12-23 22:45:18 +0000 |
commit | 175862af7b0e111d3360b1fedaa13df55d9f5d61 (patch) | |
tree | 233de9d06403c67f4c9328e9be3ff746a93525b8 | |
parent | 034a638eae18f56dfe5436a76bf0addcb13b0992 (diff) | |
download | findutils-175862af7b0e111d3360b1fedaa13df55d9f5d61.tar.gz |
xargs: Don't leak file descriptors over an exec boundary.
This fixes a bug reported by Kyle Sallee (by email, so there is no
Savannah bug number for it).
* xargs/xargs.c (fopen_cloexec_for_read_only): New function; like
fopen (..., "r") but sets the resulting file to be closed on exec.
(main): Remember any non-O_CLOEXEC file desciptors that were open
on startup so that we don't get false positives later.
(prep_child_for_exec): Call complain_about_leaky_fds.
(main): Any file opened to support the -a option is marked
close-on-exec. If we open /dev/tty to support the -p option, mark
that file close-on-exec, too.
* NEWS: mention this bugfix.
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | xargs/xargs.c | 13 |
2 files changed, 16 insertions, 2 deletions
@@ -2,6 +2,11 @@ GNU findutils NEWS - User visible changes. -*- outline -*- (allout) * Major changes in release 4.5.17-git, 2015-12-DD +** Bug Fixes: + +When the -a option of xargs is used, xargs no longer leaks a file +descriptor (fixing a bug reported by Kyle Sallee). + ** Translations Updated the Brazilian Portuguese and Serbian translations. diff --git a/xargs/xargs.c b/xargs/xargs.c index 2b0f8f28..bf130e05 100644 --- a/xargs/xargs.c +++ b/xargs/xargs.c @@ -65,6 +65,7 @@ /* find headers. */ #include "buildcmd.h" +#include "fdleak.h" #include "findutils-version.h" #if ENABLE_NLS @@ -366,6 +367,11 @@ smaller_of (size_t a, size_t b) } +static FILE* fopen_cloexec_for_read_only (const char *file_name) { + int fd = open_cloexec (file_name, O_RDONLY); + return (fd < 0) ? NULL : fdopen (fd, "r"); +} + int main (int argc, char **argv) @@ -387,6 +393,7 @@ main (int argc, char **argv) else set_program_name ("xargs"); + remember_non_cloexec_fds (); parent = getpid (); original_exit_value = EXIT_SUCCESS; @@ -678,7 +685,7 @@ main (int argc, char **argv) else { keep_stdin = 1; /* see prep_child_for_exec () */ - input_stream = fopen (input_file, "r"); + input_stream = fopen_cloexec_for_read_only (input_file); if (NULL == input_stream) { error (EXIT_FAILURE, errno, @@ -1075,7 +1082,7 @@ print_args (bool ask) if (!tty_stream) { - tty_stream = fopen ("/dev/tty", "r"); + tty_stream = fopen_cloexec_for_read_only ("/dev/tty"); if (!tty_stream) error (EXIT_FAILURE, errno, _("failed to open /dev/tty for reading")); @@ -1154,6 +1161,8 @@ set_slot_var (unsigned int n) static void prep_child_for_exec (void) { + complain_about_leaky_fds (); + /* The parent will call add_proc to allocate a slot. We do the same in the child to make sure we get the same value. |