From: Christian Göttsche Date: Mon, 6 Jan 2020 14:27:23 +0000 (+0100) Subject: selinux: add trigger for policy reload to refresh internal selabel cache X-Git-Tag: v246-rc1~790^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=61f3e897f13101f29fb8027e8839498a469ad58e;p=thirdparty%2Fsystemd.git selinux: add trigger for policy reload to refresh internal selabel cache 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 --- diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c index 1095cb426cc..5cad5641421 100644 --- a/src/basic/selinux-util.c +++ b/src/basic/selinux-util.c @@ -12,6 +12,7 @@ #include #if HAVE_SELINUX +#include #include #include #include @@ -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 { diff --git a/src/basic/selinux-util.h b/src/basic/selinux-util.h index b73b7c50e07..e3a40478cbc 100644 --- a/src/basic/selinux-util.h +++ b/src/basic/selinux-util.h @@ -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); diff --git a/src/core/main.c b/src/core/main.c index 3baecc5f00d..7bcc75856ec 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -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);