Message ID | 20200121162532.29494-1-sds@tycho.nsa.gov (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | libselinux: export flush_class_cache(), call it on policyload | expand |
On 1/21/20 11:25 AM, Stephen Smalley wrote: > Rename flush_class_cache() to selinux_flush_class_cache(), export it > for direct use by userspace policy enforcers, and call it on all policy > load notifications rather than only when using selinux_check_access(). > This ensures that policy reloads that change a userspace class or > permission value will be reflected by subsequent string_to_security_class() > or string_to_av_perm() calls. > > Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> This is now applied. This should resolve the lingering problems with dbus-daemon not getting the updated class/permission values via string_to_security_class/string_to_av_perm after a policy reload that changes the dbus class. > --- > libselinux/include/selinux/selinux.h | 3 +++ > libselinux/src/avc_internal.c | 2 ++ > libselinux/src/checkAccess.c | 13 ------------- > libselinux/src/selinux_internal.h | 3 +-- > libselinux/src/stringrep.c | 4 +++- > 5 files changed, 9 insertions(+), 16 deletions(-) > > diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h > index fe46e681488d..7922d96b70c7 100644 > --- a/libselinux/include/selinux/selinux.h > +++ b/libselinux/include/selinux/selinux.h > @@ -418,6 +418,9 @@ extern int security_av_string(security_class_t tclass, > /* Display an access vector in a string representation. */ > extern void print_access_vector(security_class_t tclass, access_vector_t av); > > +/* Flush the SELinux class cache, e.g. upon a policy reload. */ > +extern void selinux_flush_class_cache(void); > + > /* Set the function used by matchpathcon_init when displaying > errors about the file_contexts configuration. If not set, > then this defaults to fprintf(stderr, fmt, ...). */ > diff --git a/libselinux/src/avc_internal.c b/libselinux/src/avc_internal.c > index 49cecc96daee..568a3d928ac1 100644 > --- a/libselinux/src/avc_internal.c > +++ b/libselinux/src/avc_internal.c > @@ -23,6 +23,7 @@ > #include "callbacks.h" > #include "selinux_netlink.h" > #include "avc_internal.h" > +#include "selinux_internal.h" > > #ifndef NETLINK_SELINUX > #define NETLINK_SELINUX 7 > @@ -207,6 +208,7 @@ static int avc_netlink_process(void *buf) > avc_prefix, rc, errno); > return rc; > } > + selinux_flush_class_cache(); > rc = selinux_netlink_policyload(msg->seqno); > if (rc < 0) > return rc; > diff --git a/libselinux/src/checkAccess.c b/libselinux/src/checkAccess.c > index 16bfcfb63f85..7227ffe51eac 100644 > --- a/libselinux/src/checkAccess.c > +++ b/libselinux/src/checkAccess.c > @@ -10,25 +10,12 @@ > static pthread_once_t once = PTHREAD_ONCE_INIT; > static int selinux_enabled; > > -static int avc_reset_callback(uint32_t event __attribute__((unused)), > - security_id_t ssid __attribute__((unused)), > - security_id_t tsid __attribute__((unused)), > - security_class_t tclass __attribute__((unused)), > - access_vector_t perms __attribute__((unused)), > - access_vector_t *out_retained __attribute__((unused))) > -{ > - flush_class_cache(); > - return 0; > -} > - > static void avc_init_once(void) > { > selinux_enabled = is_selinux_enabled(); > if (selinux_enabled == 1) { > if (avc_open(NULL, 0)) > return; > - avc_add_callback(avc_reset_callback, AVC_CALLBACK_RESET, > - 0, 0, 0, 0); > } > } > > diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h > index 8b4bed2fd0d1..61b78aaa7c10 100644 > --- a/libselinux/src/selinux_internal.h > +++ b/libselinux/src/selinux_internal.h > @@ -107,8 +107,7 @@ hidden_proto(selinux_trans_to_raw_context); > hidden_proto(security_get_initial_context); > hidden_proto(security_get_initial_context_raw); > hidden_proto(selinux_reset_config); > - > -hidden void flush_class_cache(void); > +hidden_proto(selinux_flush_class_cache); > > extern int require_seusers hidden; > extern int selinux_page_size hidden; > diff --git a/libselinux/src/stringrep.c b/libselinux/src/stringrep.c > index 4db95398e138..29757b750878 100644 > --- a/libselinux/src/stringrep.c > +++ b/libselinux/src/stringrep.c > @@ -158,7 +158,7 @@ err1: > return NULL; > } > > -hidden void flush_class_cache(void) > +void selinux_flush_class_cache(void) > { > struct discover_class_node *cur = discover_class_cache, *prev = NULL; > size_t i; > @@ -180,6 +180,8 @@ hidden void flush_class_cache(void) > discover_class_cache = NULL; > } > > +hidden_def(selinux_flush_class_cache) > + > security_class_t string_to_security_class(const char *s) > { > struct discover_class_node *node; >
diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h index fe46e681488d..7922d96b70c7 100644 --- a/libselinux/include/selinux/selinux.h +++ b/libselinux/include/selinux/selinux.h @@ -418,6 +418,9 @@ extern int security_av_string(security_class_t tclass, /* Display an access vector in a string representation. */ extern void print_access_vector(security_class_t tclass, access_vector_t av); +/* Flush the SELinux class cache, e.g. upon a policy reload. */ +extern void selinux_flush_class_cache(void); + /* Set the function used by matchpathcon_init when displaying errors about the file_contexts configuration. If not set, then this defaults to fprintf(stderr, fmt, ...). */ diff --git a/libselinux/src/avc_internal.c b/libselinux/src/avc_internal.c index 49cecc96daee..568a3d928ac1 100644 --- a/libselinux/src/avc_internal.c +++ b/libselinux/src/avc_internal.c @@ -23,6 +23,7 @@ #include "callbacks.h" #include "selinux_netlink.h" #include "avc_internal.h" +#include "selinux_internal.h" #ifndef NETLINK_SELINUX #define NETLINK_SELINUX 7 @@ -207,6 +208,7 @@ static int avc_netlink_process(void *buf) avc_prefix, rc, errno); return rc; } + selinux_flush_class_cache(); rc = selinux_netlink_policyload(msg->seqno); if (rc < 0) return rc; diff --git a/libselinux/src/checkAccess.c b/libselinux/src/checkAccess.c index 16bfcfb63f85..7227ffe51eac 100644 --- a/libselinux/src/checkAccess.c +++ b/libselinux/src/checkAccess.c @@ -10,25 +10,12 @@ static pthread_once_t once = PTHREAD_ONCE_INIT; static int selinux_enabled; -static int avc_reset_callback(uint32_t event __attribute__((unused)), - security_id_t ssid __attribute__((unused)), - security_id_t tsid __attribute__((unused)), - security_class_t tclass __attribute__((unused)), - access_vector_t perms __attribute__((unused)), - access_vector_t *out_retained __attribute__((unused))) -{ - flush_class_cache(); - return 0; -} - static void avc_init_once(void) { selinux_enabled = is_selinux_enabled(); if (selinux_enabled == 1) { if (avc_open(NULL, 0)) return; - avc_add_callback(avc_reset_callback, AVC_CALLBACK_RESET, - 0, 0, 0, 0); } } diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h index 8b4bed2fd0d1..61b78aaa7c10 100644 --- a/libselinux/src/selinux_internal.h +++ b/libselinux/src/selinux_internal.h @@ -107,8 +107,7 @@ hidden_proto(selinux_trans_to_raw_context); hidden_proto(security_get_initial_context); hidden_proto(security_get_initial_context_raw); hidden_proto(selinux_reset_config); - -hidden void flush_class_cache(void); +hidden_proto(selinux_flush_class_cache); extern int require_seusers hidden; extern int selinux_page_size hidden; diff --git a/libselinux/src/stringrep.c b/libselinux/src/stringrep.c index 4db95398e138..29757b750878 100644 --- a/libselinux/src/stringrep.c +++ b/libselinux/src/stringrep.c @@ -158,7 +158,7 @@ err1: return NULL; } -hidden void flush_class_cache(void) +void selinux_flush_class_cache(void) { struct discover_class_node *cur = discover_class_cache, *prev = NULL; size_t i; @@ -180,6 +180,8 @@ hidden void flush_class_cache(void) discover_class_cache = NULL; } +hidden_def(selinux_flush_class_cache) + security_class_t string_to_security_class(const char *s) { struct discover_class_node *node;
Rename flush_class_cache() to selinux_flush_class_cache(), export it for direct use by userspace policy enforcers, and call it on all policy load notifications rather than only when using selinux_check_access(). This ensures that policy reloads that change a userspace class or permission value will be reflected by subsequent string_to_security_class() or string_to_av_perm() calls. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> --- libselinux/include/selinux/selinux.h | 3 +++ libselinux/src/avc_internal.c | 2 ++ libselinux/src/checkAccess.c | 13 ------------- libselinux/src/selinux_internal.h | 3 +-- libselinux/src/stringrep.c | 4 +++- 5 files changed, 9 insertions(+), 16 deletions(-)