#include <unistd.h>
#include <stdio.h>
+#if defined(WITH_SELINUX)
+#include <selinux/selinux.h>
+#include <selinux/restorecon.h>
+#include <selinux/avc.h>
+#endif
+
#include "../utils/utils.h"
#include "init.h"
#include "../watchdog.h"
}
}
+#if defined(WITH_SELINUX)
+static int
+selinux(char **argv)
+{
+ int ret;
+ int enforce = selinux_status_getenforce();
+
+ /* is SELinux already initialized? */
+ if (getenv("SELINUX_INIT")) {
+ /* have initramfs permissions already been restored? */
+ if (!getenv("INITRAMFS") || getenv("SELINUX_RESTORECON")) {
+ unsetenv("SELINUX_INIT");
+ unsetenv("SELINUX_RESTORECON");
+ return 0;
+ }
+ /* Second call (initramfs only): restore filesystem labels */
+ const char *exclude_list[] = { "/dev/console", "/proc", "/sys", 0 };
+ selinux_restorecon_set_exclude_list(exclude_list);
+ ret = selinux_restorecon("/", SELINUX_RESTORECON_RECURSE | SELINUX_RESTORECON_MASS_RELABEL);
+ putenv("SELINUX_RESTORECON=1");
+ } else {
+ /* First call: load policy */
+ ret = selinux_init_load_policy(&enforce);
+ putenv("SELINUX_INIT=1");
+ }
+
+ if (ret == 0)
+ execv(argv[0], argv);
+
+ if (enforce > 0) {
+ fprintf(stderr, "Cannot load SELinux policy, but system in enforcing mode. Halting.\n");
+ return 1;
+ }
+
+ return 0;
+}
+#else
+static int
+selinux(char **argv)
+{
+ return 0;
+}
+#endif
+
int
main(int argc, char **argv)
{
sigaction(SIGTERM, &sa_shutdown, NULL);
sigaction(SIGUSR1, &sa_shutdown, NULL);
sigaction(SIGUSR2, &sa_shutdown, NULL);
+ sigaction(SIGPWR, &sa_shutdown, NULL);
+ if (selinux(argv))
+ exit(-1);
early();
cmdline();
watchdog_init(1);
if (!pid) {
char *kmod[] = { "/sbin/kmodloader", "/etc/modules-boot.d/", NULL };
- if (debug < 3) {
- int fd = open("/dev/null", O_RDWR);
+ if (debug < 3)
+ patch_stdio("/dev/null");
- if (fd > -1) {
- dup2(fd, STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
- dup2(fd, STDERR_FILENO);
- if (fd > STDERR_FILENO)
- close(fd);
- }
- }
execvp(kmod[0], kmod);
- ERROR("Failed to start kmodloader\n");
- exit(-1);
+ ERROR("Failed to start kmodloader: %m\n");
+ exit(EXIT_FAILURE);
}
if (pid <= 0) {
- ERROR("Failed to start kmodloader instance\n");
+ ERROR("Failed to start kmodloader instance: %m\n");
} else {
+ const struct timespec req = {0, 10 * 1000 * 1000};
int i;
- for (i = 0; i < 120; i++) {
+ for (i = 0; i < 1200; i++) {
if (waitpid(pid, NULL, WNOHANG) > 0)
break;
- sleep(1);
+ nanosleep(&req, NULL);
watchdog_ping();
}
}