From 6e3e3c3416864eca74cb885f64c453eb531eed63 Mon Sep 17 00:00:00 2001 From: "harald@redhat.com" Date: Wed, 6 Oct 2004 00:54:08 -0700 Subject: [PATCH] [PATCH] PATCH udev close on exec selinux wants a clean fd set, so better close all open fds --- dev_d.c | 13 +++++++++++++ namedev.c | 6 ++---- tdb/tdb.c | 7 +++++++ udev_lib.c | 19 +++++++++++++++++++ udev_lib.h | 2 +- udevd.c | 2 ++ udevsend.c | 2 ++ 7 files changed, 46 insertions(+), 5 deletions(-) diff --git a/dev_d.c b/dev_d.c index e6081b399..c091f11c2 100644 --- a/dev_d.c +++ b/dev_d.c @@ -23,9 +23,13 @@ #include #include #include +#include #include +#include + #include "udev.h" #include "udev_lib.h" +#include "udevdb.h" #include "logging.h" #define DEVD_DIR "/etc/dev.d/" @@ -34,6 +38,7 @@ static int run_program(char *name) { pid_t pid; + int fd; dbg("running %s", name); @@ -41,6 +46,14 @@ static int run_program(char *name) switch (pid) { case 0: /* child */ + udevdb_exit(); /* close udevdb */ + fd = open("/dev/null", O_RDWR); + if ( fd >= 0) { + dup2(fd, STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + dup2(fd, STDERR_FILENO); + } + close(fd); execv(name, main_argv); dbg("exec of child failed"); exit(1); diff --git a/namedev.c b/namedev.c index c8217024c..fe7dddaf5 100644 --- a/namedev.c +++ b/namedev.c @@ -454,10 +454,8 @@ static int execute_program(char *path, char *value, int len) switch(pid) { case 0: /* child */ - close(STDOUT_FILENO); - - /* dup write side of pipe to STDOUT */ - dup(fds[1]); + /* dup2 write side of pipe to STDOUT */ + dup2(fds[1], STDOUT_FILENO); if (argv[0] != NULL) { dbg("execute '%s' with given arguments", argv[0]); retval = execv(argv[0], argv); diff --git a/tdb/tdb.c b/tdb/tdb.c index 9ae57a974..e87ea3692 100644 --- a/tdb/tdb.c +++ b/tdb/tdb.c @@ -65,6 +65,7 @@ #include #include "tdb.h" #include "spinlock.h" +#include "../udev_lib.h" #else #include "includes.h" #endif @@ -1736,6 +1737,12 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, goto fail; /* errno set by open(2) */ } + /* + Close file when execing another process. + Prevents SELinux access errors. + */ + set_cloexec_flag(tdb->fd, 1); + /* ensure there is only one process initialising at once */ if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) { TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n", diff --git a/udev_lib.c b/udev_lib.c index 8f6aa4237..4991ec3ac 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -255,3 +255,22 @@ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) closedir(dir); return 0; } + +/* Set the FD_CLOEXEC flag of desc if value is nonzero, + or clear the flag if value is 0. + Return 0 on success, or -1 on error with errno set. */ + +int set_cloexec_flag (int desc, int value) +{ + int oldflags = fcntl (desc, F_GETFD, 0); + /* If reading the flags failed, return error indication now. */ + if (oldflags < 0) + return oldflags; + /* Set just the flag we want to set. */ + if (value != 0) + oldflags |= FD_CLOEXEC; + else + oldflags &= ~FD_CLOEXEC; + /* Store modified flag word in the descriptor. */ + return fcntl (desc, F_SETFD, oldflags); +} diff --git a/udev_lib.h b/udev_lib.h index 18ce25ccc..2f1965ea3 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -78,6 +78,6 @@ extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); extern void leading_slash(char *path); extern void no_leading_slash(char *path); extern int call_foreach_file(int fnct(char *f) , char *filename, char *extension); - +extern int set_cloexec_flag (int desc, int value); #endif diff --git a/udevd.c b/udevd.c index 2bcb4a9e1..81f4474a8 100644 --- a/udevd.c +++ b/udevd.c @@ -477,6 +477,8 @@ int main(int argc, char *argv[]) exit(1); } + set_cloexec_flag(ssock, 1); + /* the bind takes care of ensuring only one copy running */ retval = bind(ssock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { diff --git a/udevsend.c b/udevsend.c index 842a2a4bc..23ba1a1b0 100644 --- a/udevsend.c +++ b/udevsend.c @@ -160,6 +160,8 @@ int main(int argc, char* argv[]) goto fallback; } + set_cloexec_flag(sock, 1); + memset(&saddr, 0x00, sizeof(struct sockaddr_un)); saddr.sun_family = AF_LOCAL; /* use abstract namespace for socket path */ -- 2.30.2