]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
selinux: add trigger for policy reload to refresh internal selabel cache
authorChristian Göttsche <cgzones@googlemail.com>
Mon, 6 Jan 2020 14:27:23 +0000 (15:27 +0100)
committerChristian Göttsche <cgzones@googlemail.com>
Tue, 3 Mar 2020 19:25:49 +0000 (20:25 +0100)
Reload the internal selabel cache automatically on SELinux policy reloads so non pid-1 daemons are participating.

Run the reload function `mac_selinux_reload()` not manually on daemon-reload, but rather pass it as callback to libselinux.
Trigger the callback prior usage of the systemd internal selabel cache by depleting the selinux netlink socket via `avc_netlink_check_nb()`.

Improves: a9dfac21ec85 ("core: reload SELinux label cache on daemon-reload")
Improves: #13363

src/basic/selinux-util.c
src/basic/selinux-util.h
src/core/main.c

index 1095cb426cce815d829dd0d8744b72fb15be9110..5cad56414211bf7b6ea4f7edf517ce19e24685ab 100644 (file)
@@ -12,6 +12,7 @@
 #include <syslog.h>
 
 #if HAVE_SELINUX
+#include <selinux/avc.h>
 #include <selinux/context.h>
 #include <selinux/label.h>
 #include <selinux/selinux.h>
@@ -31,6 +32,8 @@
 DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free);
 #define _cleanup_context_free_ _cleanup_(context_freep)
 
+static int mac_selinux_reload(int seqno);
+
 static int cached_use = -1;
 static struct selabel_handle *label_hnd = NULL;
 
@@ -62,6 +65,8 @@ int mac_selinux_init(void) {
         usec_t before_timestamp, after_timestamp;
         struct mallinfo before_mallinfo, after_mallinfo;
 
+        selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback) mac_selinux_reload);
+
         if (label_hnd)
                 return 0;
 
@@ -104,13 +109,12 @@ void mac_selinux_finish(void) {
 #endif
 }
 
-void mac_selinux_reload(void) {
-
 #if HAVE_SELINUX
+static int mac_selinux_reload(int seqno) {
         struct selabel_handle *backup_label_hnd;
 
         if (!label_hnd)
-                return;
+                return 0;
 
         backup_label_hnd = TAKE_PTR(label_hnd);
 
@@ -121,8 +125,10 @@ void mac_selinux_reload(void) {
                 selabel_close(backup_label_hnd);
         else
                 label_hnd = backup_label_hnd;
-#endif
+
+        return 0;
 }
+#endif
 
 int mac_selinux_fix(const char *path, LabelFixFlags flags) {
 
@@ -151,6 +157,9 @@ int mac_selinux_fix(const char *path, LabelFixFlags flags) {
         if (fstat(fd, &st) < 0)
                 return -errno;
 
+        /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
+        (void) avc_netlink_check_nb();
+
         if (selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode) < 0) {
                 r = -errno;
 
@@ -349,6 +358,9 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
         assert(abspath);
         assert(path_is_absolute(abspath));
 
+        /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
+        (void) avc_netlink_check_nb();
+
         r = selabel_lookup_raw(label_hnd, &filecon, abspath, mode);
         if (r < 0) {
                 /* No context specified by the policy? Proceed without setting it. */
@@ -497,6 +509,9 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
 
         path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path));
 
+        /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
+        (void) avc_netlink_check_nb();
+
         if (path_is_absolute(path))
                 r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
         else {
index b73b7c50e07414e3cba0e0037a5610d6fbf1fb65..e3a40478cbc594af1bc34a7055a0828f554187cd 100644 (file)
@@ -20,7 +20,6 @@ void mac_selinux_retest(void);
 
 int mac_selinux_init(void);
 void mac_selinux_finish(void);
-void mac_selinux_reload(void);
 
 int mac_selinux_fix(const char *path, LabelFixFlags flags);
 int mac_selinux_apply(const char *path, const char *label);
index 3baecc5f00d162c3a1d5db0cec608c4f2482c249..7bcc75856ec805eed117a8bd96921b8f169baa94 100644 (file)
@@ -1747,8 +1747,6 @@ static int invoke_main_loop(
                         saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
                         saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
 
-                        mac_selinux_reload();
-
                         (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock);
 
                         set_manager_defaults(m);