6136c1
From 4e48673172b012a06575e4f5b681d3554eded2e2 Mon Sep 17 00:00:00 2001
6136c1
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
6136c1
Date: Mon, 6 Jan 2020 15:27:23 +0100
6136c1
Subject: [PATCH] selinux: add trigger for policy reload to refresh internal
6136c1
 selabel cache
6136c1
6136c1
Reload the internal selabel cache automatically on SELinux policy reloads so non pid-1 daemons are participating.
6136c1
6136c1
Run the reload function `mac_selinux_reload()` not manually on daemon-reload, but rather pass it as callback to libselinux.
6136c1
Trigger the callback prior usage of the systemd internal selabel cache by depleting the selinux netlink socket via `avc_netlink_check_nb()`.
6136c1
6136c1
Improves: a9dfac21ec85 ("core: reload SELinux label cache on daemon-reload")
6136c1
Improves: #13363
6136c1
(cherry picked from commit 61f3e897f13101f29fb8027e8839498a469ad58e)
6136c1
6136c1
Related: #1888912
6136c1
---
6136c1
 src/basic/selinux-util.c | 23 +++++++++++++++++++----
6136c1
 src/basic/selinux-util.h |  1 -
6136c1
 src/core/main.c          |  2 --
6136c1
 3 files changed, 19 insertions(+), 7 deletions(-)
6136c1
6136c1
diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c
6136c1
index a078ce23ef..bfe3d015aa 100644
6136c1
--- a/src/basic/selinux-util.c
6136c1
+++ b/src/basic/selinux-util.c
6136c1
@@ -10,6 +10,7 @@
6136c1
 #include <syslog.h>
6136c1
 
6136c1
 #if HAVE_SELINUX
6136c1
+#include <selinux/avc.h>
6136c1
 #include <selinux/context.h>
6136c1
 #include <selinux/label.h>
6136c1
 #include <selinux/selinux.h>
6136c1
@@ -32,6 +33,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(context_t, context_free);
6136c1
 #define _cleanup_freecon_ _cleanup_(freeconp)
6136c1
 #define _cleanup_context_free_ _cleanup_(context_freep)
6136c1
 
6136c1
+static int mac_selinux_reload(int seqno);
6136c1
+
6136c1
 static int cached_use = -1;
6136c1
 static struct selabel_handle *label_hnd = NULL;
6136c1
 
6136c1
@@ -63,6 +66,8 @@ int mac_selinux_init(void) {
6136c1
         usec_t before_timestamp, after_timestamp;
6136c1
         struct mallinfo before_mallinfo, after_mallinfo;
6136c1
 
6136c1
+        selinux_set_callback(SELINUX_CB_POLICYLOAD, (union selinux_callback) mac_selinux_reload);
6136c1
+
6136c1
         if (label_hnd)
6136c1
                 return 0;
6136c1
 
6136c1
@@ -105,13 +110,12 @@ void mac_selinux_finish(void) {
6136c1
 #endif
6136c1
 }
6136c1
 
6136c1
-void mac_selinux_reload(void) {
6136c1
-
6136c1
 #if HAVE_SELINUX
6136c1
+static int mac_selinux_reload(int seqno) {
6136c1
         struct selabel_handle *backup_label_hnd;
6136c1
 
6136c1
         if (!label_hnd)
6136c1
-                return;
6136c1
+                return 0;
6136c1
 
6136c1
         backup_label_hnd = TAKE_PTR(label_hnd);
6136c1
 
6136c1
@@ -122,8 +126,10 @@ void mac_selinux_reload(void) {
6136c1
                 selabel_close(backup_label_hnd);
6136c1
         else
6136c1
                 label_hnd = backup_label_hnd;
6136c1
-#endif
6136c1
+
6136c1
+        return 0;
6136c1
 }
6136c1
+#endif
6136c1
 
6136c1
 int mac_selinux_fix(const char *path, LabelFixFlags flags) {
6136c1
 
6136c1
@@ -152,6 +158,9 @@ int mac_selinux_fix(const char *path, LabelFixFlags flags) {
6136c1
         if (fstat(fd, &st) < 0)
6136c1
                 return -errno;
6136c1
 
6136c1
+        /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
6136c1
+        (void) avc_netlink_check_nb();
6136c1
+
6136c1
         if (selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode) < 0) {
6136c1
                 r = -errno;
6136c1
 
6136c1
@@ -345,6 +354,9 @@ static int selinux_create_file_prepare_abspath(const char *abspath, mode_t mode)
6136c1
         assert(abspath);
6136c1
         assert(path_is_absolute(abspath));
6136c1
 
6136c1
+        /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
6136c1
+        (void) avc_netlink_check_nb();
6136c1
+
6136c1
         r = selabel_lookup_raw(label_hnd, &filecon, abspath, mode);
6136c1
         if (r < 0) {
6136c1
                 /* No context specified by the policy? Proceed without setting it. */
6136c1
@@ -496,6 +508,9 @@ int mac_selinux_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
6136c1
 
6136c1
         path = strndupa(un->sun_path, addrlen - offsetof(struct sockaddr_un, sun_path));
6136c1
 
6136c1
+        /* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
6136c1
+        (void) avc_netlink_check_nb();
6136c1
+
6136c1
         if (path_is_absolute(path))
6136c1
                 r = selabel_lookup_raw(label_hnd, &fcon, path, S_IFSOCK);
6136c1
         else {
6136c1
diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h
6136c1
index 639c35b687..bd5207c318 100644
6136c1
--- a/src/basic/selinux-util.h
6136c1
+++ b/src/basic/selinux-util.h
6136c1
@@ -13,7 +13,6 @@ void mac_selinux_retest(void);
6136c1
 
6136c1
 int mac_selinux_init(void);
6136c1
 void mac_selinux_finish(void);
6136c1
-void mac_selinux_reload(void);
6136c1
 
6136c1
 int mac_selinux_fix(const char *path, LabelFixFlags flags);
6136c1
 int mac_selinux_apply(const char *path, const char *label);
6136c1
diff --git a/src/core/main.c b/src/core/main.c
6136c1
index d5c41da0c4..d897155644 100644
6136c1
--- a/src/core/main.c
6136c1
+++ b/src/core/main.c
6136c1
@@ -1682,8 +1682,6 @@ static int invoke_main_loop(
6136c1
                         saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
6136c1
                         saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
6136c1
 
6136c1
-                        mac_selinux_reload();
6136c1
-
6136c1
                         (void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock);
6136c1
 
6136c1
                         set_manager_defaults(m);