Close any unexpectedly inherited fds in helper monitor and init.

tingping/wmclass
Alexander Larsson 2015-05-06 18:04:35 +02:00
parent 4e1856bed1
commit 34d7c14394
2 changed files with 76 additions and 1 deletions

View File

@ -43,6 +43,8 @@ AC_ARG_WITH(system_fonts_dir,
SYSTEM_FONTS_DIR=$with_system_fonts_dir
AC_SUBST(SYSTEM_FONTS_DIR)
AC_CHECK_FUNCS(fdwalk)
AC_CHECK_HEADER([sys/xattr.h], [], AC_MSG_ERROR([You must have sys/xattr.h from glibc]))
AC_CHECK_HEADER([sys/capability.h], have_caps=yes, AC_MSG_ERROR([sys/capability.h header not found]))

View File

@ -16,7 +16,8 @@
*
*/
#define _GNU_SOURCE /* Required for CLONE_NEWNS */
#include "config.h"
#include <assert.h>
#include <arpa/inet.h>
#include <dirent.h>
@ -228,6 +229,59 @@ strdup_printf (const char *format,
return buffer;
}
#ifndef HAVE_FDWALK
static int
fdwalk (int (*cb)(void *data, int fd), void *data)
{
int open_max;
int fd;
int res = 0;
DIR *d;
if ((d = opendir ("/proc/self/fd")))
{
struct dirent *de;
while ((de = readdir (d)))
{
long l;
char *e = NULL;
if (de->d_name[0] == '.')
continue;
errno = 0;
l = strtol (de->d_name, &e, 10);
if (errno != 0 || !e || *e)
continue;
fd = (int) l;
if ((long) fd != l)
continue;
if (fd == dirfd (d))
continue;
if ((res = cb (data, fd)) != 0)
break;
}
closedir (d);
return res;
}
open_max = sysconf (_SC_OPEN_MAX);
for (fd = 0; fd < open_max; fd++)
if ((res = cb (data, fd)) != 0)
break;
return res;
}
#endif
static inline int raw_clone(unsigned long flags, void *child_stack) {
#if defined(__s390__) || defined(__CRIS__)
/* On s390 and cris the order of the first and second arguments
@ -1217,6 +1271,17 @@ block_sigchild (void)
die_with_error ("sigprocmask");
}
static int
close_extra_fds (void *data, int fd)
{
int event_fd = (int) (ssize_t) (data);
if (fd >= 3 && fd != event_fd)
close (fd);
return 0;
}
/* This stays around for as long as the initial process in the app does
* and when that exits it exits, propagating the exit status. We do this
* by having pid1 in the sandbox detect this exit and tell the monitor
@ -1234,6 +1299,10 @@ monitor_child (int event_fd)
struct pollfd fds[2];
struct signalfd_siginfo fdsi;
/* Close all extra fds in the monitoring process.
Any passed in fds have been passed on to the child anyway. */
fdwalk (close_extra_fds, (void *)(ssize_t)event_fd);
sigemptyset (&mask);
sigaddset (&mask, SIGCHLD);
@ -1806,6 +1875,10 @@ main (int argc,
return 0;
}
/* Close all extra fds in pid 1.
Any passed in fds have been passed on to the child anyway. */
fdwalk (close_extra_fds, (void *)(ssize_t)event_fd);
strncpy (argv[0], "xdg-app-init\0", strlen (argv[0]));
return do_init (event_fd, pid);
}