We're looking to move to a different init system in Fedora - the current work is going to be around upstart, most likely. upstart does not have native code for loading the SELinux policy. We could modify every possible init to load the policy... but that would be painful. So we might as well move to having the policy loaded from the initramfs. The attached patches are the first quick cut at doing that. The main patch is for mkinitrd/nash; there's a short patch for the current init, as it will abort if policy is already loaded. We can't actually remove the code from init to load the policy, as there will always be older initramfses. Comments? Ideas for different ways to do this? It's sort of ugly with fork and chroot(), but to avoid that we'd have to reimplement most, if not all, of libselinux's policy loading code directly. Bill
diff -up mkinitrd-6.0.28/nash/nash.c.foo mkinitrd-6.0.28/nash/nash.c --- mkinitrd-6.0.28/nash/nash.c.foo 2008-01-09 12:12:28.000000000 -0500 +++ mkinitrd-6.0.28/nash/nash.c 2008-01-23 16:59:15.000000000 -0500 @@ -60,6 +60,8 @@ #include <libdevmapper.h> +#include <selinux/selinux.h> + #include <bdevid.h> #include <nash.h> @@ -1719,6 +1721,34 @@ mkdirCommand(char * cmd, char * end) } static int +loadPolicyCommand(char * cmd, char *end) +{ + int enforce = 0; + int pid, status; + + pid = fork(); + + if (pid == 0) { + if (chroot("/sysroot") != 0) { + eprintf("load_policy: chroot failed: %m\n"); + exit(0); + } + + if (selinux_init_load_policy(&enforce) != 0) { + if (enforce > 0) { + eprintf("Unable to load SELinux policy (%m). Halting now.\n"); + exit(1); + } + exit(0); + } + exit(0); + } + waitpid(pid, &status, 0); + if (!WIFEXITED(status) || WEXITSTATUS(status)) exit(1); + return 0; +} + +static int accessCommand(char * cmd, char * end) { char * permStr; @@ -2728,6 +2758,7 @@ static const struct commandHandler handl { "find", findCommand }, { "kernelopt", printKernelOpt }, { "loadDrivers", loadDriversCommand }, + { "loadpolicy", loadPolicyCommand }, { "mkblktab", mkblktabCommand }, { "mkblkdevs", mkblkdevsCommand }, { "mkdir", mkdirCommand }, diff -up mkinitrd-6.0.28/mkinitrd.foo mkinitrd-6.0.28/mkinitrd --- mkinitrd-6.0.28/mkinitrd.foo 2008-01-23 17:09:26.000000000 -0500 +++ mkinitrd-6.0.28/mkinitrd 2008-01-23 17:10:23.000000000 -0500 @@ -1692,6 +1692,13 @@ if [ -n "$dhclient_leases_cmd" ]; then emit "$dhclient_leases_cmd" fi +SELINUX= +[ -f /etc/selinux/config ] && . /etc/selinux/config +if [ -n "$SELINUX" -a "$SELINUX" != "disabled" ]; then + emit "echo Loading SELinux policy." + emit "loadpolicy" +fi + emit "echo Switching to new root and running init." emit "switchroot" emit "echo Booting has failed."
diff -ru sysvinit-2.86/src/init.c sysvinit-2.86/src/init.c --- sysvinit-2.86/src/init.c 2008-01-23 17:10:45.000000000 -0500 +++ sysvinit-2.86/src/init.c 2008-01-23 16:26:07.000000000 -0500 @@ -2671,7 +2671,7 @@ maxproclen += strlen(argv[f]) + 1; } - if (getenv("SELINUX_INIT") == NULL) { + if (getenv("SELINUX_INIT") == NULL && !is_selinux_enabled()) { putenv("SELINUX_INIT=YES"); if (selinux_init_load_policy(&enforce) == 0 ) { execv(myname, argv);
-- fedora-selinux-list mailing list fedora-selinux-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/fedora-selinux-list