[systemd-commits] 4 commits - Makefile.am src/label.c src/label.h src/main.c src/mount-setup.c src/selinux-setup.c src/selinux-setup.h src/util.c src/util.h units/fedora

Lennart Poettering lennart at kemper.freedesktop.org
Tue Oct 26 20:47:59 PDT 2010


 Makefile.am                     |    1 
 src/label.c                     |   28 +++++++++++++++++
 src/label.h                     |    1 
 src/main.c                      |   20 +++---------
 src/mount-setup.c               |   35 +++++++++++++++++++++
 src/selinux-setup.c             |   64 ++++++++++++++++++++++++++++++++++++++++
 src/selinux-setup.h             |   27 ++++++++++++++++
 src/util.c                      |    9 +++++
 src/util.h                      |    4 ++
 units/fedora/halt-local.service |    1 
 units/fedora/rc-local.service   |    1 
 units/fedora/sysinit.service    |    1 
 12 files changed, 178 insertions(+), 14 deletions(-)

New commits:
commit 5c0532d1cc989d2f78d2cd4a18058daa58143705
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 27 05:47:48 2010 +0200

    mounts: automatically create /dev/stderr and friends early on boot so that they are around when we run shell scripts before udevd

diff --git a/src/label.c b/src/label.c
index 01f36eb..d037c4c 100644
--- a/src/label.c
+++ b/src/label.c
@@ -173,6 +173,31 @@ int label_fifofile_set(const char *path) {
         return r;
 }
 
+int label_symlinkfile_set(const char *path) {
+        int r = 0;
+
+#ifdef HAVE_SELINUX
+        security_context_t filecon = NULL;
+
+        if (!use_selinux() || !label_hnd)
+                return 0;
+
+        if ((r = selabel_lookup_raw(label_hnd, &filecon, path, S_IFLNK)) == 0) {
+                if ((r = setfscreatecon(filecon)) < 0) {
+                        log_error("Failed to set SELinux file context on %s: %m", path);
+                        r = -errno;
+                }
+
+                freecon(filecon);
+        }
+
+        if (r < 0 && security_getenforce() == 0)
+                r = 0;
+#endif
+
+        return r;
+}
+
 int label_socket_set(const char *label) {
 
 #ifdef HAVE_SELINUX
diff --git a/src/label.h b/src/label.h
index 0c59da1..f1bf5d6 100644
--- a/src/label.h
+++ b/src/label.h
@@ -33,6 +33,7 @@ int label_socket_set(const char *label);
 void label_socket_clear(void);
 
 int label_fifofile_set(const char *path);
+int label_symlinkfile_set(const char *path);
 void label_file_clear(void);
 
 void label_free(const char *label);
diff --git a/src/mount-setup.c b/src/mount-setup.c
index d2f05bc..fe99f58 100644
--- a/src/mount-setup.c
+++ b/src/mount-setup.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <libgen.h>
 #include <assert.h>
+#include <unistd.h>
 
 #include "mount-setup.h"
 #include "log.h"
@@ -171,13 +172,47 @@ finish:
         return r;
 }
 
+static int symlink_and_label(const char *old_path, const char *new_path) {
+        int r;
+
+        assert(old_path);
+        assert(new_path);
+
+        if ((r = label_symlinkfile_set(new_path)) < 0)
+                return r;
+
+        if (symlink(old_path, new_path) < 0)
+                r = -errno;
+
+        label_file_clear();
+
+        return r;
+}
+
 int mount_setup(void) {
+
+        const char *symlinks =
+                "/proc/kcore\0"      "/dev/core\0"
+                "/proc/self/fd\0"    "/dev/fd\0"
+                "/proc/self/fd/0\0"  "/dev/stdin\0"
+                "/proc/self/fd/1\0"  "/dev/stdout\0"
+                "/proc/self/fd/2\0"  "/dev/stderr\0"
+                "\0";
+
         int r;
         unsigned i;
+        const char *j, *k;
 
         for (i = 0; i < ELEMENTSOF(mount_table); i ++)
                 if ((r = mount_one(mount_table+i)) < 0)
                         return r;
 
+        /* Create a few default symlinks, which are normally created
+         * bei udevd, but some scripts might need them before we start
+         * udevd. */
+
+        NULSTR_FOREACH_PAIR(j, k, symlinks)
+                symlink_and_label(j, k);
+
         return mount_cgroup_controllers();
 }
diff --git a/src/util.h b/src/util.h
index ddf089c..3256fba 100644
--- a/src/util.h
+++ b/src/util.h
@@ -373,6 +373,9 @@ void dual_timestamp_deserialize(FILE *f, const char *line, dual_timestamp *t);
 #define NULSTR_FOREACH(i, l) \
         for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)
 
+#define NULSTR_FOREACH_PAIR(i, j, l)                             \
+        for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
+
 const char *ioprio_class_to_string(int i);
 int ioprio_class_from_string(const char *s);
 

commit c4dcdb9f4785937f2b73700e66b8cafa452f60a7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 27 05:47:02 2010 +0200

    selinux: automatically load policy if the initrd hasn't done this for us yet

diff --git a/Makefile.am b/Makefile.am
index 5c4a2e7..e079ac8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -399,6 +399,7 @@ libsystemd_core_la_SOURCES = \
 	src/cgroup.c \
 	src/mount-setup.c \
 	src/hostname-setup.c \
+	src/selinux-setup.c \
 	src/loopback-setup.c \
 	src/kmod-setup.c \
 	src/locale-setup.c \
diff --git a/src/label.c b/src/label.c
index 809b1ee..01f36eb 100644
--- a/src/label.c
+++ b/src/label.c
@@ -51,6 +51,9 @@ int label_init(void) {
         if (!use_selinux())
                 return 0;
 
+        if (label_hnd)
+                return 0;
+
         label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
         if (!label_hnd) {
                 log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
diff --git a/src/main.c b/src/main.c
index 83cf2e7..f7d76a2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,6 +39,7 @@
 #include "loopback-setup.h"
 #include "kmod-setup.h"
 #include "locale-setup.h"
+#include "selinux-setup.h"
 #include "load-fragment.h"
 #include "fdset.h"
 #include "special.h"
@@ -895,6 +896,11 @@ int main(int argc, char *argv[]) {
                 arg_running_as = MANAGER_SYSTEM;
                 log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
 
+                /* This might actually not return, but cause a
+                 * reexecution */
+                if (selinux_setup(argv) < 0)
+                        goto finish;
+
                 if (label_init() < 0)
                         goto finish;
         } else {
diff --git a/src/selinux-setup.c b/src/selinux-setup.c
new file mode 100644
index 0000000..d4da693
--- /dev/null
+++ b/src/selinux-setup.c
@@ -0,0 +1,64 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd 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.
+
+  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#include "selinux-setup.h"
+#include "macro.h"
+#include "util.h"
+#include "log.h"
+
+int selinux_setup(char *const argv[]) {
+#ifdef HAVE_SELINUX
+       int enforce = 0;
+
+       /* Already initialized? */
+       if (path_is_mount_point("/selinux") > 0)
+               return 0;
+
+       if (selinux_init_load_policy(&enforce) == 0) {
+               log_info("Successfully loaded SELinux policy, reexecuting.");
+
+               /* FIXME: Ideally we'd just call setcon() here instead
+                * of having to reexecute ourselves here. */
+
+               execv(SYSTEMD_BINARY_PATH, argv);
+               log_error("Failed to reexecute: %m");
+               return -errno;
+
+       } else {
+               log_full(enforce > 0 ? LOG_ERR : LOG_DEBUG, "Failed to load SELinux policy.");
+
+               if (enforce > 0)
+                       return -EIO;
+       }
+#endif
+
+       return 0;
+}
diff --git a/src/selinux-setup.h b/src/selinux-setup.h
new file mode 100644
index 0000000..53dbb65
--- /dev/null
+++ b/src/selinux-setup.h
@@ -0,0 +1,27 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#ifndef fooselinuxsetuphfoo
+#define fooselinuxsetuphfoo
+
+/***
+  This file is part of systemd.
+
+  Copyright 2010 Lennart Poettering
+
+  systemd 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.
+
+  systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+int selinux_setup(char *const argv[]);
+
+#endif

commit ade509ce73ba1de3bcda8b012961a3045f721df7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 27 05:45:57 2010 +0200

    main: move make_null_stdio() to util.c

diff --git a/src/main.c b/src/main.c
index 7dad015..83cf2e7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -180,20 +180,6 @@ static void install_crash_handler(void) {
         sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
 }
 
-static int make_null_stdio(void) {
-        int null_fd, r;
-
-        if ((null_fd = open("/dev/null", O_RDWR|O_NOCTTY)) < 0) {
-                log_error("Failed to open /dev/null: %m");
-                return -errno;
-        }
-
-        if ((r = make_stdio(null_fd)) < 0)
-                log_warning("Failed to dup2() device: %s", strerror(-r));
-
-        return r;
-}
-
 static int console_setup(bool do_reset) {
         int tty_fd, r;
 
diff --git a/src/util.c b/src/util.c
index d653d6b..9a82c71 100644
--- a/src/util.c
+++ b/src/util.c
@@ -2605,6 +2605,15 @@ int make_stdio(int fd) {
         return 0;
 }
 
+int make_null_stdio(void) {
+        int null_fd;
+
+        if ((null_fd = open("/dev/null", O_RDWR|O_NOCTTY)) < 0)
+                return -errno;
+
+        return make_stdio(null_fd);
+}
+
 bool is_clean_exit(int code, int status) {
 
         if (code == CLD_EXITED)
diff --git a/src/util.h b/src/util.h
index 71889f1..ddf089c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -265,6 +265,7 @@ char *format_timestamp_pretty(char *buf, size_t l, usec_t t);
 char *format_timespan(char *buf, size_t l, usec_t t);
 
 int make_stdio(int fd);
+int make_null_stdio(void);
 
 bool is_clean_exit(int code, int status);
 bool is_clean_exit_lsb(int code, int status);

commit 4690698d4949d8b42e4c3a87944075ceaf685e5a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Oct 27 05:45:09 2010 +0200

    units: run sysv related scripts with TERM=linux

diff --git a/units/fedora/halt-local.service b/units/fedora/halt-local.service
index 79f8f12..855924a 100644
--- a/units/fedora/halt-local.service
+++ b/units/fedora/halt-local.service
@@ -14,6 +14,7 @@ Before=final.target
 
 [Service]
 Type=oneshot
+Environment=TERM=linux
 ExecStart=/sbin/halt.local
 TimeoutSec=0
 StandardOutput=tty
diff --git a/units/fedora/rc-local.service b/units/fedora/rc-local.service
index 564969c..fb27694 100644
--- a/units/fedora/rc-local.service
+++ b/units/fedora/rc-local.service
@@ -15,6 +15,7 @@ Names=rc-local.service local.service
 
 [Service]
 Type=forking
+Environment=TERM=linux
 ExecStart=/etc/rc.local start
 TimeoutSec=0
 StandardOutput=tty
diff --git a/units/fedora/sysinit.service b/units/fedora/sysinit.service
index 5e28462..9e83baa 100644
--- a/units/fedora/sysinit.service
+++ b/units/fedora/sysinit.service
@@ -13,6 +13,7 @@ After=systemd-readahead-collect.service systemd-readahead-replay.service
 Before=shutdown.target emergency.service emergency.target
 
 [Service]
+Environment=TERM=linux
 ExecStart=/etc/rc.d/rc.sysinit
 Type=forking
 TimeoutSec=0



More information about the systemd-commits mailing list