From e598c5738c2dc85a3e93c3f68cd88e8eea51215b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 2 Oct 2008 18:48:40 +0200 Subject: [PATCH] libudev: get rid of selinux "Hello world!" linked against libselinux parses /proc/mounts and whatever else on startup, even when the lib is not needed at all. Not funny! Get rid of that thing where it's not absolutely needed. --- Makefile.am.inc | 3 +- TODO | 2 + extras/ata_id/Makefile.am | 5 -- extras/cdrom_id/Makefile.am | 5 -- extras/edd_id/Makefile.am | 5 -- extras/floppy/Makefile.am | 3 +- extras/floppy/create_floppy_devices.c | 2 + extras/fstab_import/Makefile.am | 5 -- extras/scsi_id/Makefile.am | 5 -- extras/usb_id/Makefile.am | 5 -- extras/volume_id/Makefile.am | 5 -- udev/Makefile.am | 1 + udev/lib/libudev.c | 91 ------------------------ udev/lib/libudev.h | 5 -- udev/test-udev.c | 2 + udev/udev.h | 7 ++ udev/udev_selinux.c | 99 +++++++++++++++++++++++++++ udev/udevadm.c | 2 + udev/udevd.c | 3 + 19 files changed, 122 insertions(+), 133 deletions(-) create mode 100644 udev/udev_selinux.c diff --git a/Makefile.am.inc b/Makefile.am.inc index f61706a2c..7ecd55de7 100644 --- a/Makefile.am.inc +++ b/Makefile.am.inc @@ -6,4 +6,5 @@ AM_CPPFLAGS = \ AM_CFLAGS = -AM_LDFLAGS = +AM_LDFLAGS = \ + -Wl,--as-needed diff --git a/TODO b/TODO index f960f2431..082bb478e 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,5 @@ + convert usb_id to libudev's udev_device + o handle spaces in SYMLINK+=, do not create multiple links o use libudev device in udev_rules.c get rid of udevice, store rule matching state in rule iterator diff --git a/extras/ata_id/Makefile.am b/extras/ata_id/Makefile.am index 89aa02f5d..34ded29de 100644 --- a/extras/ata_id/Makefile.am +++ b/extras/ata_id/Makefile.am @@ -10,11 +10,6 @@ ata_id_SOURCES = \ ../../udev/lib/libudev.c \ ../../udev/lib/libudev-util.c -if USE_SELINUX -ata_id_LDADD = \ - $(SELINUX_LIBS) -endif - dist_man_MANS = \ ata_id.8 diff --git a/extras/cdrom_id/Makefile.am b/extras/cdrom_id/Makefile.am index ec14366a2..f8c4bbff0 100644 --- a/extras/cdrom_id/Makefile.am +++ b/extras/cdrom_id/Makefile.am @@ -14,11 +14,6 @@ cdrom_id_SOURCES = \ ../../udev/lib/libudev.c \ ../../udev/lib/libudev-util.c -if USE_SELINUX -cdrom_id_LDADD = \ - $(SELINUX_LIBS) -endif - dist_man_MANS = \ cdrom_id.8 diff --git a/extras/edd_id/Makefile.am b/extras/edd_id/Makefile.am index 652d2c472..67199fd23 100644 --- a/extras/edd_id/Makefile.am +++ b/extras/edd_id/Makefile.am @@ -14,11 +14,6 @@ edd_id_SOURCES = \ ../../udev/lib/libudev.c \ ../../udev/lib/libudev-util.c -if USE_SELINUX -edd_id_LDADD = \ - $(SELINUX_LIBS) -endif - dist_man_MANS = \ edd_id.8 diff --git a/extras/floppy/Makefile.am b/extras/floppy/Makefile.am index a62dd2098..337e7a325 100644 --- a/extras/floppy/Makefile.am +++ b/extras/floppy/Makefile.am @@ -9,7 +9,8 @@ create_floppy_devices_SOURCES = \ ../../udev/lib/libudev.h \ ../../udev/lib/libudev.c \ ../../udev/lib/libudev-util.c \ - ../../udev/udev_utils.c + ../../udev/udev_utils.c \ + ../../udev/udev_selinux.c if USE_SELINUX create_floppy_devices_LDADD = \ diff --git a/extras/floppy/create_floppy_devices.c b/extras/floppy/create_floppy_devices.c index 4cff958da..6c5b3b480 100644 --- a/extras/floppy/create_floppy_devices.c +++ b/extras/floppy/create_floppy_devices.c @@ -68,6 +68,7 @@ int main(int argc, char **argv) logging_init("create_floppy_devices"); udev_set_log_fn(udev, log_fn); + selinux_init(udev); while ((c = getopt(argc, argv, "cudm:U:G:M:t:")) != -1) { switch (c) { @@ -161,6 +162,7 @@ int main(int argc, char **argv) i++; } + selinux_exit(udev); udev_unref(udev); exit: return 0; diff --git a/extras/fstab_import/Makefile.am b/extras/fstab_import/Makefile.am index 49e598e1f..c1204782b 100644 --- a/extras/fstab_import/Makefile.am +++ b/extras/fstab_import/Makefile.am @@ -14,11 +14,6 @@ fstab_import_SOURCES = \ ../../udev/lib/libudev.c \ ../../udev/lib/libudev-util.c -if USE_SELINUX -fstab_import_LDADD = \ - $(SELINUX_LIBS) -endif - distclean-local: rm -f Makefile.in diff --git a/extras/scsi_id/Makefile.am b/extras/scsi_id/Makefile.am index 0b5dbf045..e6798eea6 100644 --- a/extras/scsi_id/Makefile.am +++ b/extras/scsi_id/Makefile.am @@ -14,11 +14,6 @@ scsi_id_SOURCES = \ ../../udev/lib/libudev.c \ ../../udev/lib/libudev-util.c -if USE_SELINUX -scsi_id_LDADD = \ - $(SELINUX_LIBS) -endif - dist_sysconf_DATA = \ scsi_id.config diff --git a/extras/usb_id/Makefile.am b/extras/usb_id/Makefile.am index 89d59657f..24f630b1d 100644 --- a/extras/usb_id/Makefile.am +++ b/extras/usb_id/Makefile.am @@ -12,10 +12,5 @@ usb_id_SOURCES = \ ../../udev/udev_sysfs.c \ ../../udev/udev_utils.c -if USE_SELINUX -usb_id_LDADD = \ - $(SELINUX_LIBS) -endif - distclean-local: rm -f Makefile.in diff --git a/extras/volume_id/Makefile.am b/extras/volume_id/Makefile.am index 4d904d83c..5b68e4321 100644 --- a/extras/volume_id/Makefile.am +++ b/extras/volume_id/Makefile.am @@ -16,11 +16,6 @@ vol_id_SOURCES = \ vol_id_LDADD = \ lib/libvolume_id.la -if USE_SELINUX -vol_id_LDADD += \ - $(SELINUX_LIBS) -endif - dist_man_MANS = \ vol_id.8 diff --git a/udev/Makefile.am b/udev/Makefile.am index b28546b51..b9e2e8962 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 c2c5025b9..3f7d0e547 100644 --- a/udev/lib/libudev.c +++ b/udev/lib/libudev.c @@ -25,9 +25,6 @@ #include #include #include -#ifdef USE_SELINUX -#include -#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 fec05d447..448346e27 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 4aa7999fc..508f9f140 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 102f15d0b..b54d313bf 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 000000000..499f53c91 --- /dev/null +++ b/udev/udev_selinux.c @@ -0,0 +1,99 @@ +/* + * libudev - interface to udev device information + * + * Copyright (C) 2008 Kay Sievers + * + * 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 . + */ + +#include +#include +#include +#include +#include + +#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 + +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 3f2c78212..3671b9ee5 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 a821ee7d8..4000d37e8 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; } -- 2.30.2