chiark / gitweb /
[PATCH] PATCH udev close on exec
authorharald@redhat.com <harald@redhat.com>
Wed, 6 Oct 2004 07:54:08 +0000 (00:54 -0700)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:37:03 +0000 (21:37 -0700)
selinux wants a clean fd set, so better close all open fds

dev_d.c
namedev.c
tdb/tdb.c
udev_lib.c
udev_lib.h
udevd.c
udevsend.c

diff --git a/dev_d.c b/dev_d.c
index e6081b3993fe6b75696b50aa0b40637ebb003f67..c091f11c28726cc02d5a165bdecd38d7befad1da 100644 (file)
--- a/dev_d.c
+++ b/dev_d.c
 #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);
index c8217024c87070e20a953269105440bf1853d07a..fe7dddaf55bafa0138562a731d67d4738c310906 100644 (file)
--- 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);
index 9ae57a974e08cf1054b4a51b19988f065a7d4228..e87ea3692eb555f2cea013cb94f98b14acd2cd0a 100644 (file)
--- a/tdb/tdb.c
+++ b/tdb/tdb.c
@@ -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",
index 8f6aa4237734a906c609484c0b8e6626cc7ecbc8..4991ec3acb4447699b34e2a643c76429a5d04833 100644 (file)
@@ -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);
+}
index 18ce25ccc791475a450888747171ebc22fe7065b..2f1965ea32ac4f5743879f09260544d238634c0a 100644 (file)
@@ -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 2bcb4a9e1ec4fd7d8b3cc525b4e8534d71274702..81f4474a89b6bc7df5ddd834cff3180d0cb12bdf 100644 (file)
--- 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) {
index 842a2a4bc4178578b6663b74dc54cbfaa2a3de29..23ba1a1b000b206953d95514fc7ab94423486ac7 100644 (file)
@@ -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 */