[systemd-devel] [PATCH] honor SELinux labels, when creating and writing config files

harald at redhat.com harald at redhat.com
Thu Feb 14 03:27:26 PST 2013


From: Harald Hoyer <harald at redhat.com>

see https://bugzilla.redhat.com/show_bug.cgi?id=881577
---
 Makefile.am              |   2 +
 src/core/unit.c          |   3 +-
 src/hostname/hostnamed.c |   7 ++--
 src/locale/localed.c     |   7 ++--
 src/login/logind-dbus.c  |   4 +-
 src/shared/label.c       | 103 +++++++++++++++++++++++++++++++++++++++++++++++
 src/shared/label.h       |   4 ++
 src/timedate/timedated.c |   5 ++-
 8 files changed, 125 insertions(+), 10 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 403439b..1a19b8b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2898,6 +2898,7 @@ systemd_hostnamed_CFLAGS = \
 	$(DBUS_CFLAGS)
 
 systemd_hostnamed_LDADD = \
+	libsystemd-label.la \
 	libsystemd-shared.la \
 	libsystemd-daemon.la \
 	libsystemd-dbus.la
@@ -3034,6 +3035,7 @@ systemd_timedated_CFLAGS = \
 	$(DBUS_CFLAGS)
 
 systemd_timedated_LDADD = \
+	libsystemd-label.la \
 	libsystemd-shared.la \
 	libsystemd-daemon.la \
 	libsystemd-dbus.la
diff --git a/src/core/unit.c b/src/core/unit.c
index f7d00b6..52603ab 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -46,6 +46,7 @@
 #include "missing.h"
 #include "cgroup-attr.h"
 #include "mkdir.h"
+#include "label.h"
 
 const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
         [UNIT_SERVICE] = &service_vtable,
@@ -2778,7 +2779,7 @@ int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data
                 return -ENOMEM;
 
         mkdir_p(p, 0755);
-        return write_one_line_file_atomic(q, data);
+        return label_write_one_line_file_atomic(q, data);
 }
 
 int unit_remove_drop_in(Unit *u, bool runtime, const char *name) {
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index c5a8b6f..14a8376 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -33,6 +33,7 @@
 #include "def.h"
 #include "virt.h"
 #include "env-util.h"
+#include "label.h"
 
 #define INTERFACE \
         " <interface name=\"org.freedesktop.hostname1\">\n"             \
@@ -287,8 +288,7 @@ static int write_data_static_hostname(void) {
 
                 return 0;
         }
-
-        return write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
+        return label_write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
 }
 
 static int write_data_other(void) {
@@ -338,7 +338,7 @@ static int write_data_other(void) {
                 return 0;
         }
 
-        r = write_env_file("/etc/machine-info", l);
+        r = label_write_env_file("/etc/machine-info", l);
         strv_free(l);
 
         return r;
@@ -683,6 +683,7 @@ int main(int argc, char *argv[]) {
         log_open();
 
         umask(0022);
+        label_init("/etc");
 
         if (argc == 2 && streq(argv[1], "--introspect")) {
                 fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
diff --git a/src/locale/localed.c b/src/locale/localed.c
index fedcdfb..317291d 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -32,6 +32,7 @@
 #include "polkit.h"
 #include "def.h"
 #include "env-util.h"
+#include "label.h"
 
 #define INTERFACE                                                       \
         " <interface name=\"org.freedesktop.locale1\">\n"               \
@@ -390,7 +391,7 @@ static int write_data_locale(void) {
                 return 0;
         }
 
-        r = write_env_file("/etc/locale.conf", l);
+        r = label_write_env_file("/etc/locale.conf", l);
         strv_free(l);
 
         return r;
@@ -546,7 +547,7 @@ static int write_data_vconsole(void) {
                 return 0;
         }
 
-        r = write_env_file("/etc/vconsole.conf", l);
+        r = label_write_env_file("/etc/vconsole.conf", l);
         strv_free(l);
 
         return r;
@@ -1364,7 +1365,7 @@ int main(int argc, char *argv[]) {
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
         log_open();
-
+        label_init("/etc");
         umask(0022);
 
         if (argc == 2 && streq(argv[1], "--introspect")) {
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index f351859..fadaa25 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -33,6 +33,7 @@
 #include "special.h"
 #include "systemd/sd-id128.h"
 #include "systemd/sd-messages.h"
+#include "label.h"
 
 #define BUS_MANAGER_INTERFACE                                           \
         " <interface name=\"org.freedesktop.login1.Manager\">\n"        \
@@ -937,7 +938,8 @@ static int attach_device(Manager *m, const char *seat, const char *sysfs) {
         }
 
         mkdir_p_label("/etc/udev/rules.d", 0755);
-        r = write_one_line_file_atomic(file, rule);
+        label_init("/etc");
+        r = label_write_one_line_file_atomic(file, rule);
         if (r < 0)
                 goto finish;
 
diff --git a/src/shared/label.c b/src/shared/label.c
index d353da5..e2ac4c5 100644
--- a/src/shared/label.c
+++ b/src/shared/label.c
@@ -25,8 +25,12 @@
 #include <malloc.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include "label.h"
+#include "strv.h"
 #include "util.h"
 #include "path-util.h"
 
@@ -380,3 +384,102 @@ skipped:
 #endif
         return bind(fd, addr, addrlen) < 0 ? -errno : 0;
 }
+
+int label_write_one_line_file_atomic(const char *fn, const char *line) {
+        _cleanup_fclose_ FILE *f = NULL;
+        _cleanup_free_ char *p = NULL;
+        int r;
+
+        assert(fn);
+        assert(line);
+
+        r = label_fopen_temporary(fn, &f, &p);
+        if (r < 0)
+                return r;
+
+        fchmod_umask(fileno(f), 0644);
+
+        errno = 0;
+        if (fputs(line, f) < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (!endswith(line, "\n"))
+                fputc('\n', f);
+
+        fflush(f);
+
+        if (ferror(f))
+                r = errno ? -errno : -EIO;
+        else {
+                if (rename(p, fn) < 0)
+                        r = -errno;
+                else
+                        r = 0;
+        }
+
+finish:
+        if (r < 0)
+                unlink(p);
+
+        return r;
+}
+
+int label_write_env_file(const char *fname, char **l) {
+        char **i, *p;
+        FILE *f;
+        int r;
+
+        r = label_fopen_temporary(fname, &f, &p);
+        if (r < 0)
+                return r;
+
+        fchmod_umask(fileno(f), 0644);
+
+        errno = 0;
+        STRV_FOREACH(i, l) {
+                fputs(*i, f);
+                fputc('\n', f);
+        }
+
+        fflush(f);
+
+        if (ferror(f)) {
+                if (errno != 0)
+                        r = -errno;
+                else
+                        r = -EIO;
+        } else {
+                if (rename(p, fname) < 0)
+                        r = -errno;
+                else
+                        r = 0;
+        }
+
+        if (r < 0)
+                unlink(p);
+
+        fclose(f);
+        free(p);
+
+        return r;
+}
+
+int label_fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
+        int r;
+
+        assert(path);
+        assert(_f);
+        assert(_temp_path);
+
+        r = label_context_set(path, S_IFREG);
+        if (r  < 0)
+                return r;
+
+        r = fopen_temporary(path, _f, _temp_path);
+
+        label_context_clear();
+
+        return r;
+}
diff --git a/src/shared/label.h b/src/shared/label.h
index 1220b18..dda4d1c 100644
--- a/src/shared/label.h
+++ b/src/shared/label.h
@@ -45,3 +45,7 @@ int label_mkdir(const char *path, mode_t mode, bool apply);
 void label_retest_selinux(void);
 
 int label_bind(int fd, const struct sockaddr *addr, socklen_t addrlen);
+
+int label_write_one_line_file_atomic(const char *fn, const char *line);
+int label_write_env_file(const char *fname, char **l);
+int label_fopen_temporary(const char *path, FILE **_f, char **_temp_path);
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index b8c6b36..44f7bd9 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -35,6 +35,7 @@
 #include "hwclock.h"
 #include "conf-files.h"
 #include "path-util.h"
+#include "label.h"
 
 #define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
 #define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
@@ -269,8 +270,8 @@ static int write_data_local_rtc(void) {
                         return 0;
                 }
         }
-
-        r = write_one_line_file_atomic("/etc/adjtime", w);
+        label_init("/etc");
+        r = label_write_one_line_file_atomic("/etc/adjtime", w);
         free(w);
 
         return r;
-- 
1.8.1



More information about the systemd-devel mailing list