summaryrefslogtreecommitdiff
path: root/udev
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2008-09-10 00:46:17 +0200
committerKay Sievers <kay.sievers@vrfy.org>2008-09-10 00:46:17 +0200
commit4f4b12c20388ff2cb158b040e3193f86cf7a3b96 (patch)
tree41449172690d16f6deba140d174343478f806d23 /udev
parent6b12bdb62460a0bdc08d5e020a64c18bc1672bb1 (diff)
libudev: add selinux
Diffstat (limited to 'udev')
-rw-r--r--udev/Makefile.am5
-rw-r--r--udev/lib/Makefile.am5
-rw-r--r--udev/lib/libudev.c83
-rw-r--r--udev/lib/libudev.h3
-rw-r--r--udev/test-udev.c3
-rw-r--r--udev/udev.h2
-rw-r--r--udev/udev_db.c6
-rw-r--r--udev/udev_node.c21
-rw-r--r--udev/udev_rules.c1
-rw-r--r--udev/udev_rules_parse.c5
-rw-r--r--udev/udev_selinux.c175
-rw-r--r--udev/udev_selinux.h35
-rw-r--r--udev/udev_utils_file.c5
-rw-r--r--udev/udevd.c8
14 files changed, 103 insertions, 254 deletions
diff --git a/udev/Makefile.am b/udev/Makefile.am
index de39249af1..7984e5d5f9 100644
--- a/udev/Makefile.am
+++ b/udev/Makefile.am
@@ -20,7 +20,6 @@ common_files = \
logging.h \
udev.h \
udev_rules.h \
- udev_selinux.h \
udev_sysdeps.h \
udev_db.c \
udev_device.c \
@@ -41,11 +40,7 @@ common_files = \
lib/libudev-utils.c \
lib/libudev-ctrl.c
-
if USE_SELINUX
-common_files += \
- udev_selinux.c
-
common_ldadd += \
$(SELINUX_LIBS)
endif
diff --git a/udev/lib/Makefile.am b/udev/lib/Makefile.am
index 630888d3d9..95dd46e92f 100644
--- a/udev/lib/Makefile.am
+++ b/udev/lib/Makefile.am
@@ -38,11 +38,6 @@ libudev_la_SOURCES =\
../udev_db.c \
../udev_sysdeps.c
-if USE_SELINUX
-libudev_la_SOURCES += \
- ../udev_selinux.c
-endif
-
libudev_la_LDFLAGS = \
-version-info $(LIBUDEV_LT_CURRENT):$(LIBUDEV_LT_REVISION):$(LIBUDEV_LT_AGE) \
-export-symbols $(top_srcdir)/udev/lib/exported_symbols
diff --git a/udev/lib/libudev.c b/udev/lib/libudev.c
index 09e1bec1bf..4e258bd2ce 100644
--- a/udev/lib/libudev.c
+++ b/udev/lib/libudev.c
@@ -27,6 +27,9 @@
#include <errno.h>
#include <string.h>
#include <ctype.h>
+#ifdef USE_SELINUX
+#include <selinux/selinux.h>
+#endif
#include "libudev.h"
#include "libudev-private.h"
@@ -41,6 +44,10 @@ struct udev {
char *dev_path;
char *rules_path;
int log_priority;
+#ifdef USE_SELINUX
+ int selinux_enabled;
+ security_context_t selinux_prev_scontext;
+#endif
int run:1;
};
@@ -66,6 +73,78 @@ static void log_stderr(struct udev *udev,
vfprintf(stderr, format, args);
}
+static void selinux_init(struct udev *udev)
+{
+#ifdef USE_SELINUX
+ /*
+ * record the present security context, for file-creation
+ * restoration creation purposes.
+ */
+ udev->selinux_enabled = (is_selinux_enabled() > 0);
+ if (udev->selinux_enabled) {
+ matchpathcon_init_prefix(NULL, udev_get_dev_path(udev));
+ if (getfscreatecon(&udev->selinux_prev_scontext) < 0) {
+ err(udev, "getfscreatecon failed\n");
+ udev->selinux_prev_scontext = NULL;
+ }
+ }
+#endif
+}
+
+static void selinux_exit(struct udev *udev)
+{
+#ifdef USE_SELINUX
+ if (udev->selinux_enabled) {
+ freecon(udev->selinux_prev_scontext);
+ udev->selinux_prev_scontext = NULL;
+ }
+#endif
+}
+
+void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode)
+{
+#ifdef USE_SELINUX
+ if (udev->selinux_enabled) {
+ security_context_t scontext = NULL;
+
+ if (matchpathcon(file, mode, &scontext) < 0) {
+ err(udev, "matchpathcon(%s) failed\n", file);
+ return;
+ }
+ if (lsetfilecon(file, scontext) < 0)
+ err(udev, "setfilecon %s failed: %s\n", file, strerror(errno));
+ freecon(scontext);
+ }
+#endif
+}
+
+void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode)
+{
+#ifdef USE_SELINUX
+ if (udev->selinux_enabled) {
+ security_context_t scontext = NULL;
+
+ if (matchpathcon(file, mode, &scontext) < 0) {
+ err(udev, "matchpathcon(%s) failed\n", file);
+ return;
+ }
+ if (setfscreatecon(scontext) < 0)
+ err(udev, "setfscreatecon %s failed: %s\n", file, strerror(errno));
+ freecon(scontext);
+ }
+#endif
+}
+
+void udev_selinux_resetfscreatecon(struct udev *udev)
+{
+#ifdef USE_SELINUX
+ if (udev->selinux_enabled) {
+ if (setfscreatecon(udev->selinux_prev_scontext) < 0)
+ err(udev, "setfscreatecon failed: %s\n", strerror(errno));
+ }
+#endif
+}
+
/**
* udev_new:
*
@@ -88,9 +167,8 @@ struct udev *udev_new(void)
return NULL;
memset(udev, 0x00, (sizeof(struct udev)));
+ selinux_init(udev);
sysfs_init();
-
- /* defaults */
udev->refcount = 1;
udev->log_fn = log_stderr;
udev->log_priority = LOG_ERR;
@@ -270,6 +348,7 @@ void udev_unref(struct udev *udev)
if (udev->refcount > 0)
return;
sysfs_cleanup();
+ selinux_exit(udev);
free(udev->dev_path);
free(udev->sys_path);
free(udev->rules_path);
diff --git a/udev/lib/libudev.h b/udev/lib/libudev.h
index 2fd990f92e..e1eed568f9 100644
--- a/udev/lib/libudev.h
+++ b/udev/lib/libudev.h
@@ -40,6 +40,9 @@ extern int udev_get_log_priority(struct udev *udev);
extern void udev_set_log_priority(struct udev *udev, int priority);
extern const char *udev_get_sys_path(struct udev *udev);
extern const char *udev_get_dev_path(struct udev *udev);
+extern void udev_selinux_resetfscreatecon(struct udev *udev);
+extern void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode);
+extern void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode);
struct udev_device;
extern struct udev_device *udev_device_new_from_devpath(struct udev *udev, const char *devpath);
diff --git a/udev/test-udev.c b/udev/test-udev.c
index 6c01bdbcd4..58bc28e02a 100644
--- a/udev/test-udev.c
+++ b/udev/test-udev.c
@@ -33,7 +33,6 @@
#include "udev.h"
#include "udev_rules.h"
-#include "udev_selinux.h"
static void asmlinkage sig_handler(int signum)
{
@@ -63,7 +62,6 @@ int main(int argc, char *argv[])
if (udev == NULL)
exit(1);
dbg(udev, "version %s\n", VERSION);
- selinux_init(udev);
/* set signal handlers */
memset(&act, 0x00, sizeof(act));
@@ -135,7 +133,6 @@ int main(int argc, char *argv[])
fail:
udev_rules_cleanup(&rules);
sysfs_cleanup();
- selinux_exit(udev);
exit:
udev_unref(udev);
if (retval != 0)
diff --git a/udev/udev.h b/udev/udev.h
index 122e83d876..700c8c09d8 100644
--- a/udev/udev.h
+++ b/udev/udev.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2003-2006 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2003-2008 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
diff --git a/udev/udev_db.c b/udev/udev_db.c
index e89f2c2a15..18e111ba4b 100644
--- a/udev/udev_db.c
+++ b/udev/udev_db.c
@@ -31,8 +31,6 @@
#include <sys/types.h>
#include "udev.h"
-#include "udev_selinux.h"
-
static size_t devpath_to_db_path(struct udev *udev, const char *devpath, char *filename, size_t len)
{
@@ -147,9 +145,9 @@ int udev_db_add_device(struct udevice *udevice)
!udevice->partitions && !udevice->ignore_remove) {
int ret;
dbg(udevice->udev, "nothing interesting to store, create symlink\n");
- selinux_setfscreatecon(udevice->udev, filename, NULL, S_IFLNK);
+ udev_selinux_setfscreatecon(udevice->udev, filename, S_IFLNK);
ret = symlink(udevice->name, filename);
- selinux_resetfscreatecon(udevice->udev);
+ udev_selinux_resetfscreatecon(udevice->udev);
if (ret != 0) {
err(udevice->udev, "unable to create db link '%s': %s\n", filename, strerror(errno));
return -1;
diff --git a/udev/udev_node.c b/udev/udev_node.c
index 462f1b633b..079bb4e3b1 100644
--- a/udev/udev_node.c
+++ b/udev/udev_node.c
@@ -31,7 +31,6 @@
#include "udev.h"
#include "udev_rules.h"
-#include "udev_selinux.h"
#define TMP_FILE_EXT ".udev-tmp"
@@ -51,15 +50,15 @@ int udev_node_mknod(struct udevice *udevice, const char *file, dev_t devt, mode_
if (((stats.st_mode & S_IFMT) == (mode & S_IFMT)) && (stats.st_rdev == devt)) {
info(udevice->udev, "preserve file '%s', because it has correct dev_t\n", file);
preserve = 1;
- selinux_setfilecon(udevice->udev, file, udevice->dev->kernel, mode);
+ udev_selinux_lsetfilecon(udevice->udev, file, mode);
} else {
info(udevice->udev, "atomically replace existing file '%s'\n", file);
strlcpy(file_tmp, file, sizeof(file_tmp));
strlcat(file_tmp, TMP_FILE_EXT, sizeof(file_tmp));
unlink(file_tmp);
- selinux_setfscreatecon(udevice->udev, file_tmp, udevice->dev->kernel, mode);
+ udev_selinux_setfscreatecon(udevice->udev, file_tmp, mode);
err = mknod(file_tmp, mode, devt);
- selinux_resetfscreatecon(udevice->udev);
+ udev_selinux_resetfscreatecon(udevice->udev);
if (err != 0) {
err(udevice->udev, "mknod(%s, %#o, %u, %u) failed: %s\n",
file_tmp, mode, major(devt), minor(devt), strerror(errno));
@@ -73,9 +72,9 @@ int udev_node_mknod(struct udevice *udevice, const char *file, dev_t devt, mode_
}
} else {
info(udevice->udev, "mknod(%s, %#o, (%u,%u))\n", file, mode, major(devt), minor(devt));
- selinux_setfscreatecon(udevice->udev, file, udevice->dev->kernel, mode);
+ udev_selinux_setfscreatecon(udevice->udev, file, mode);
err = mknod(file, mode, devt);
- selinux_resetfscreatecon(udevice->udev);
+ udev_selinux_resetfscreatecon(udevice->udev);
if (err != 0) {
err(udevice->udev, "mknod(%s, %#o, (%u,%u) failed: %s\n",
file, mode, major(devt), minor(devt), strerror(errno));
@@ -151,16 +150,16 @@ static int node_symlink(struct udevice *udevice, const char *node, const char *s
buf[len] = '\0';
if (strcmp(target, buf) == 0) {
info(udevice->udev, "preserve already existing symlink '%s' to '%s'\n", slink, target);
- selinux_setfilecon(udevice->udev, slink, NULL, S_IFLNK);
+ udev_selinux_lsetfilecon(udevice->udev, slink, S_IFLNK);
goto exit;
}
}
}
} else {
info(udevice->udev, "creating symlink '%s' to '%s'\n", slink, target);
- selinux_setfscreatecon(udevice->udev, slink, NULL, S_IFLNK);
+ udev_selinux_setfscreatecon(udevice->udev, slink, S_IFLNK);
retval = symlink(target, slink);
- selinux_resetfscreatecon(udevice->udev);
+ udev_selinux_resetfscreatecon(udevice->udev);
if (retval == 0)
goto exit;
}
@@ -169,9 +168,9 @@ static int node_symlink(struct udevice *udevice, const char *node, const char *s
strlcpy(slink_tmp, slink, sizeof(slink_tmp));
strlcat(slink_tmp, TMP_FILE_EXT, sizeof(slink_tmp));
unlink(slink_tmp);
- selinux_setfscreatecon(udevice->udev, slink, NULL, S_IFLNK);
+ udev_selinux_setfscreatecon(udevice->udev, slink, S_IFLNK);
retval = symlink(target, slink_tmp);
- selinux_resetfscreatecon(udevice->udev);
+ udev_selinux_resetfscreatecon(udevice->udev);
if (retval != 0) {
err(udevice->udev, "symlink(%s, %s) failed: %s\n", target, slink_tmp, strerror(errno));
goto exit;
diff --git a/udev/udev_rules.c b/udev/udev_rules.c
index 3b9631b883..6e4a6942f8 100644
--- a/udev/udev_rules.c
+++ b/udev/udev_rules.c
@@ -35,7 +35,6 @@
#include "udev.h"
#include "udev_rules.h"
-#include "udev_selinux.h"
extern char **environ;
diff --git a/udev/udev_rules_parse.c b/udev/udev_rules_parse.c
index 81f0edb6f5..9513ac9cf3 100644
--- a/udev/udev_rules_parse.c
+++ b/udev/udev_rules_parse.c
@@ -30,7 +30,6 @@
#include "udev.h"
#include "udev_rules.h"
-#include "udev_selinux.h"
void udev_rules_iter_init(struct udev_rules_iter *iter, struct udev_rules *rules)
@@ -756,9 +755,9 @@ int udev_rules_init(struct udev *udev, struct udev_rules *rules, int resolve_nam
strlcat(filename, "/.udev/rules.d", sizeof(filename));
if (stat(filename, &statbuf) != 0) {
create_path(udev, filename);
- selinux_setfscreatecon(udev, filename, NULL, S_IFDIR|0755);
+ udev_selinux_setfscreatecon(udev, filename, S_IFDIR|0755);
mkdir(filename, 0755);
- selinux_resetfscreatecon(udev);
+ udev_selinux_resetfscreatecon(udev);
}
add_matching_files(udev, &sort_list, filename, ".rules");
diff --git a/udev/udev_selinux.c b/udev/udev_selinux.c
deleted file mode 100644
index 2e76a7431f..0000000000
--- a/udev/udev_selinux.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2004 Daniel Walsh
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <limits.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <selinux/selinux.h>
-
-#include "udev.h"
-#include "udev_selinux.h"
-
-static security_context_t prev_scontext = NULL;
-
-static int is_selinux_running(struct udev *udev)
-{
- static int selinux_enabled = -1;
-
- if (selinux_enabled == -1)
- selinux_enabled = (is_selinux_enabled() > 0);
-
- dbg(udev, "selinux=%i\n", selinux_enabled);
- return selinux_enabled;
-}
-
-static char *get_media(struct udev *udev, const char *devname, int mode)
-{
- FILE *fp;
- char procfile[PATH_MAX];
- char mediabuf[256];
- int size;
- char *media = NULL;
-
- if (!(mode & S_IFBLK))
- return NULL;
-
- snprintf(procfile, PATH_MAX, "/proc/ide/%s/media", devname);
- procfile[PATH_MAX-1] = '\0';
-
- fp = fopen(procfile, "r");
- if (!fp)
- goto out;
-
- if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL)
- goto close_out;
-
- size = strlen(mediabuf);
- while (size-- > 0) {
- if (isspace(mediabuf[size])) {
- mediabuf[size] = '\0';
- } else {
- break;
- }
- }
-
- media = strdup(mediabuf);
- info(udev, "selinux_get_media(%s)='%s'\n", devname, media);
-
-close_out:
- fclose(fp);
-out:
- return media;
-}
-
-void selinux_setfilecon(struct udev *udev, const char *file, const char *devname, unsigned int mode)
-{
- if (is_selinux_running(udev)) {
- security_context_t scontext = NULL;
- char *media;
- int ret = -1;
-
- if (devname) {
- media = get_media(udev, devname, mode);
- if (media) {
- ret = matchmediacon(media, &scontext);
- free(media);
- }
- }
-
- if (ret < 0)
- if (matchpathcon(file, mode, &scontext) < 0) {
- err(udev, "matchpathcon(%s) failed\n", file);
- return;
- }
-
- if (lsetfilecon(file, scontext) < 0)
- err(udev, "setfilecon %s failed: %s\n", file, strerror(errno));
-
- freecon(scontext);
- }
-}
-
-void selinux_setfscreatecon(struct udev *udev, const char *file, const char *devname, unsigned int mode)
-{
- if (is_selinux_running(udev)) {
- security_context_t scontext = NULL;
- char *media;
- int ret = -1;
-
- if (devname) {
- media = get_media(udev, devname, mode);
- if (media) {
- ret = matchmediacon(media, &scontext);
- free(media);
- }
- }
-
- if (ret < 0)
- if (matchpathcon(file, mode, &scontext) < 0) {
- err(udev, "matchpathcon(%s) failed\n", file);
- return;
- }
-
- if (setfscreatecon(scontext) < 0)
- err(udev, "setfscreatecon %s failed: %s\n", file, strerror(errno));
-
- freecon(scontext);
- }
-}
-
-void selinux_resetfscreatecon(struct udev *udev)
-{
- if (is_selinux_running(udev)) {
- if (setfscreatecon(prev_scontext) < 0)
- err(udev, "setfscreatecon failed: %s\n", strerror(errno));
- }
-}
-
-void selinux_init(struct udev *udev)
-{
- /*
- * record the present security context, for file-creation
- * restoration creation purposes.
- */
- if (is_selinux_running(udev)) {
- if (!udev_get_dev_path(udev)[0])
- err(udev, "selinux_init: udev_root not set\n");
- matchpathcon_init_prefix(NULL, udev_get_dev_path(udev));
- if (getfscreatecon(&prev_scontext) < 0) {
- err(udev, "getfscreatecon failed\n");
- prev_scontext = NULL;
- }
- }
-}
-
-void selinux_exit(struct udev *udev)
-{
- if (is_selinux_running(udev) && prev_scontext) {
- freecon(prev_scontext);
- prev_scontext = NULL;
- }
-}
diff --git a/udev/udev_selinux.h b/udev/udev_selinux.h
deleted file mode 100644
index 55bc91222a..0000000000
--- a/udev/udev_selinux.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2004 Daniel Walsh
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-#ifndef _UDEV_SELINUX_H
-#define _UDEV_SELINUX_H
-
-#ifdef USE_SELINUX
-extern void selinux_setfilecon(struct udev *udev, const char *file, const char *devname, unsigned int mode);
-extern void selinux_setfscreatecon(struct udev *udev, const char *file, const char *devname, unsigned int mode);
-extern void selinux_resetfscreatecon(struct udev *udev);
-extern void selinux_init(struct udev *udev);
-extern void selinux_exit(struct udev *udev);
-#else
-static inline void selinux_setfilecon(struct udev *udev, const char *file, const char *devname, unsigned int mode) {}
-static inline void selinux_setfscreatecon(struct udev *udev, const char *file, const char *devname, unsigned int mode) {}
-static inline void selinux_resetfscreatecon(struct udev *udev) {}
-static inline void selinux_init(struct udev *udev) {}
-static inline void selinux_exit(struct udev *udev) {}
-#endif
-
-#endif
diff --git a/udev/udev_utils_file.c b/udev/udev_utils_file.c
index 7ccb5b4039..b8b4d10d21 100644
--- a/udev/udev_utils_file.c
+++ b/udev/udev_utils_file.c
@@ -30,7 +30,6 @@
#include <sys/mman.h>
#include "udev.h"
-#include "udev_selinux.h"
int create_path(struct udev *udev, const char *path)
{
@@ -56,9 +55,9 @@ int create_path(struct udev *udev, const char *path)
return -1;
dbg(udev, "mkdir '%s'\n", p);
- selinux_setfscreatecon(udev, p, NULL, S_IFDIR|0755);
+ udev_selinux_setfscreatecon(udev, p, S_IFDIR|0755);
ret = mkdir(p, 0755);
- selinux_resetfscreatecon(udev);
+ udev_selinux_resetfscreatecon(udev);
if (ret == 0)
return 0;
diff --git a/udev/udevd.c b/udev/udevd.c
index a24ca92517..d24d8430ca 100644
--- a/udev/udevd.c
+++ b/udev/udevd.c
@@ -47,7 +47,6 @@
#include "udev.h"
#include "udev_rules.h"
-#include "udev_selinux.h"
#define UDEVD_PRIORITY -4
#define UDEV_PRIORITY -2
@@ -189,9 +188,9 @@ static void export_event_state(struct udevd_uevent_msg *msg, enum event_state st
unlink(filename_failed);
delete_path(msg->udev, filename_failed);
create_path(msg->udev, filename);
- selinux_setfscreatecon(msg->udev, filename, NULL, S_IFLNK);
+ udev_selinux_setfscreatecon(msg->udev, filename, S_IFLNK);
symlink(msg->devpath, filename);
- selinux_resetfscreatecon(msg->udev);
+ udev_selinux_resetfscreatecon(msg->udev);
break;
case EVENT_FINISHED:
if (msg->devpath_old != NULL) {
@@ -804,8 +803,6 @@ int main(int argc, char *argv[])
logging_init("udevd");
udev_set_log_fn(udev, log_fn);
-
- selinux_init(udev);
dbg(udev, "version %s\n", VERSION);
while (1) {
@@ -1107,7 +1104,6 @@ int main(int argc, char *argv[])
exit:
udev_rules_cleanup(&rules);
sysfs_cleanup();
- selinux_exit(udev);
if (signal_pipe[READ_END] >= 0)
close(signal_pipe[READ_END]);