summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Youngman <jay@gnu.org>2015-12-23 22:45:18 +0000
committerJames Youngman <jay@gnu.org>2015-12-23 22:45:18 +0000
commit175862af7b0e111d3360b1fedaa13df55d9f5d61 (patch)
tree233de9d06403c67f4c9328e9be3ff746a93525b8
parent034a638eae18f56dfe5436a76bf0addcb13b0992 (diff)
downloadfindutils-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--NEWS5
-rw-r--r--xargs/xargs.c13
2 files changed, 16 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index e04ac9bf..5c429b3a 100644
--- a/NEWS
+++ b/NEWS
@@ -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.