summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorharald@redhat.com <harald@redhat.com>2004-10-06 00:54:08 -0700
committerGreg KH <gregkh@suse.de>2005-04-26 21:37:03 -0700
commit6e3e3c3416864eca74cb885f64c453eb531eed63 (patch)
treeb467f72775c46db6b8a208a61236027fce422e6a
parentc8fa2d8b413f7cf1ab42d1c35865952649bfccad (diff)
downloadsystemd-6e3e3c3416864eca74cb885f64c453eb531eed63.tar.gz
[PATCH] PATCH udev close on exec
selinux wants a clean fd set, so better close all open fds
-rw-r--r--dev_d.c13
-rw-r--r--namedev.c6
-rw-r--r--tdb/tdb.c7
-rw-r--r--udev_lib.c19
-rw-r--r--udev_lib.h2
-rw-r--r--udevd.c2
-rw-r--r--udevsend.c2
7 files changed, 46 insertions, 5 deletions
diff --git a/dev_d.c b/dev_d.c
index e6081b3993..c091f11c28 100644
--- a/dev_d.c
+++ b/dev_d.c
@@ -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);
diff --git a/namedev.c b/namedev.c
index c8217024c8..fe7dddaf55 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 9ae57a974e..e87ea3692e 100644
--- 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",
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
diff --git a/udevd.c b/udevd.c
index 2bcb4a9e1e..81f4474a89 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 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 */