diff options
Diffstat (limited to 'udev')
-rw-r--r-- | udev/Makefile.am | 1 | ||||
-rw-r--r-- | udev/lib/libudev.c | 91 | ||||
-rw-r--r-- | udev/lib/libudev.h | 5 | ||||
-rw-r--r-- | udev/test-udev.c | 2 | ||||
-rw-r--r-- | udev/udev.h | 7 | ||||
-rw-r--r-- | udev/udev_selinux.c | 99 | ||||
-rw-r--r-- | udev/udevadm.c | 2 | ||||
-rw-r--r-- | udev/udevd.c | 3 |
8 files changed, 114 insertions, 96 deletions
diff --git a/udev/Makefile.am b/udev/Makefile.am index b28546b51c..b9e2e89620 100644 --- a/udev/Makefile.am +++ b/udev/Makefile.am @@ -25,6 +25,7 @@ common_files = \ udev_sysfs.c \ udev_utils.c \ udev_utils_file.c \ + udev_selinux.c \ list.h \ lib/libudev.h \ lib/libudev-private.h \ diff --git a/udev/lib/libudev.c b/udev/lib/libudev.c index c2c5025b9e..3f7d0e547e 100644 --- a/udev/lib/libudev.c +++ b/udev/lib/libudev.c @@ -25,9 +25,6 @@ #include <errno.h> #include <string.h> #include <ctype.h> -#ifdef USE_SELINUX -#include <selinux/selinux.h> -#endif #include "libudev.h" #include "libudev-private.h" @@ -42,11 +39,6 @@ struct udev { char *dev_path; char *rules_path; int log_priority; -#ifdef USE_SELINUX - int selinux_initialized; - int selinux_enabled; - security_context_t selinux_prev_scontext; -#endif int run; }; @@ -72,26 +64,6 @@ 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); - info(udev, "selinux=%i\n", udev->selinux_enabled); - 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; - } - } - udev->selinux_initialized = 1; -#endif -} - void *udev_get_userdata(struct udev *udev) { if (udev == NULL) @@ -106,68 +78,6 @@ void udev_set_userdata(struct udev *udev, void *userdata) udev->userdata = userdata; } -static void selinux_exit(struct udev *udev) -{ -#ifdef USE_SELINUX - if (!udev->selinux_initialized) - return; - 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_initialized) - selinux_init(udev); - 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: %m\n", file); - freecon(scontext); - } -#endif -} - -void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode) -{ -#ifdef USE_SELINUX - if (!udev->selinux_initialized) - selinux_init(udev); - 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: %m\n", file); - freecon(scontext); - } -#endif -} - -void udev_selinux_resetfscreatecon(struct udev *udev) -{ -#ifdef USE_SELINUX - if (!udev->selinux_initialized) - selinux_init(udev); - if (udev->selinux_enabled) { - if (setfscreatecon(udev->selinux_prev_scontext) < 0) - err(udev, "setfscreatecon failed: %m\n"); - } -#endif -} - /** * udev_new: * @@ -364,7 +274,6 @@ void udev_unref(struct udev *udev) udev->refcount--; if (udev->refcount > 0) return; - 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 fec05d4476..448346e278 100644 --- a/udev/lib/libudev.h +++ b/udev/lib/libudev.h @@ -44,11 +44,6 @@ extern const char *udev_get_dev_path(struct udev *udev); extern void *udev_get_userdata(struct udev *udev); extern void udev_set_userdata(struct udev *udev, void *userdata); -/* selinux glue */ -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); - /* list iteration */ struct udev_list_entry; extern struct udev_list_entry *udev_list_entry_get_next(struct udev_list_entry *list_entry); diff --git a/udev/test-udev.c b/udev/test-udev.c index 4aa7999fc0..508f9f1408 100644 --- a/udev/test-udev.c +++ b/udev/test-udev.c @@ -59,6 +59,7 @@ 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)); @@ -131,6 +132,7 @@ fail: udev_rules_cleanup(&rules); sysfs_cleanup(); exit: + selinux_exit(udev); udev_unref(udev); if (retval != 0) return 1; diff --git a/udev/udev.h b/udev/udev.h index 102f15d0b9..b54d313bff 100644 --- a/udev/udev.h +++ b/udev/udev.h @@ -167,6 +167,13 @@ extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(void *buf, size_t bufsize); extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); +/* udev_selinux */ +extern void selinux_init(struct udev *udev); +extern void selinux_exit(struct udev *udev); +extern void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode); +extern void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode); +extern void udev_selinux_resetfscreatecon(struct udev *udev); + /* udevadm commands */ extern int udevadm_monitor(struct udev *udev, int argc, char *argv[]); extern int udevadm_info(struct udev *udev, int argc, char *argv[]); diff --git a/udev/udev_selinux.c b/udev/udev_selinux.c new file mode 100644 index 0000000000..499f53c916 --- /dev/null +++ b/udev/udev_selinux.c @@ -0,0 +1,99 @@ +/* + * libudev - interface to udev device information + * + * Copyright (C) 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 Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <stdarg.h> +#include <unistd.h> + +#include "udev.h" + +#ifndef USE_SELINUX +void selinux_init(struct udev *udev) {} +void selinux_exit(struct udev *udev) {} +void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode) {} +void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode) {} +void udev_selinux_resetfscreatecon(struct udev *udev) {} +#else +#include <selinux/selinux.h> + +static int selinux_enabled; +security_context_t selinux_prev_scontext; + +void selinux_init(struct udev *udev) +{ + /* record the present security context */ + selinux_enabled = (is_selinux_enabled() > 0); + info(udev, "selinux=%i\n", selinux_enabled); + if (!selinux_enabled) + return; + matchpathcon_init_prefix(NULL, udev_get_dev_path(udev)); + if (getfscreatecon(&selinux_prev_scontext) < 0) { + err(udev, "getfscreatecon failed\n"); + selinux_prev_scontext = NULL; + } +} + +void selinux_exit(struct udev *udev) +{ + if (!selinux_enabled) + return; + freecon(selinux_prev_scontext); + selinux_prev_scontext = NULL; +} + +void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode) +{ + security_context_t scontext = NULL; + + if (!selinux_enabled) + return; + if (matchpathcon(file, mode, &scontext) < 0) { + err(udev, "matchpathcon(%s) failed\n", file); + return; + } + if (lsetfilecon(file, scontext) < 0) + err(udev, "setfilecon %s failed: %m\n", file); + freecon(scontext); +} + +void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode) +{ + security_context_t scontext = NULL; + + if (!selinux_enabled) + return; + if (matchpathcon(file, mode, &scontext) < 0) { + err(udev, "matchpathcon(%s) failed\n", file); + return; + } + if (setfscreatecon(scontext) < 0) + err(udev, "setfscreatecon %s failed: %m\n", file); + freecon(scontext); +} + +void udev_selinux_resetfscreatecon(struct udev *udev) +{ + if (!selinux_enabled) + return; + if (setfscreatecon(selinux_prev_scontext) < 0) + err(udev, "setfscreatecon failed: %m\n"); +} +#endif diff --git a/udev/udevadm.c b/udev/udevadm.c index 3f2c78212e..3671b9ee59 100644 --- a/udev/udevadm.c +++ b/udev/udevadm.c @@ -140,6 +140,7 @@ int main(int argc, char *argv[]) logging_init("udevadm"); udev_set_log_fn(udev, log_fn); + selinux_init(udev); sysfs_init(); /* see if we are a compat link, this will be removed in a future release */ @@ -211,6 +212,7 @@ int main(int argc, char *argv[]) rc = 2; out: sysfs_cleanup(); + selinux_exit(udev); udev_unref(udev); logging_close(); return rc; diff --git a/udev/udevd.c b/udev/udevd.c index a821ee7d8e..4000d37e80 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -801,6 +801,7 @@ int main(int argc, char *argv[]) logging_init("udevd"); udev_set_log_fn(udev, log_fn); dbg(udev, "version %s\n", VERSION); + selinux_init(udev); while (1) { int option; @@ -1125,6 +1126,8 @@ exit: if (uevent_netlink_sock >= 0) close(uevent_netlink_sock); + selinux_exit(udev); + udev_unref(udev); logging_close(); return rc; } |