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: a9dfac21ec ("core: reload SELinux label cache on daemon-reload")
Improves: #13363
This commit is contained in:
Christian Göttsche
2020-03-03 20:25:49 +01:00
parent 1699f53788
commit 61f3e897f1
3 changed files with 19 additions and 7 deletions
+19 -4
View 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 {
-1
View 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);