diff options
-rw-r--r-- | dev_d.c | 13 | ||||
-rw-r--r-- | namedev.c | 6 | ||||
-rw-r--r-- | tdb/tdb.c | 7 | ||||
-rw-r--r-- | udev_lib.c | 19 | ||||
-rw-r--r-- | udev_lib.h | 2 | ||||
-rw-r--r-- | udevd.c | 2 | ||||
-rw-r--r-- | udevsend.c | 2 |
7 files changed, 46 insertions, 5 deletions
@@ -23,9 +23,13 @@ #include <string.h> #include <sys/types.h> #include <sys/wait.h> +#include <sys/stat.h> #include <unistd.h> +#include <fcntl.h> + #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); @@ -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); @@ -65,6 +65,7 @@ #include <signal.h> #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 8f6aa42377..4991ec3acb 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 18ce25ccc7..2f1965ea32 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 @@ -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 842a2a4bc4..23ba1a1b00 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 */ |