diff mbox series

libselinux: export flush_class_cache(), call it on policyload

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

Commit Message

Stephen Smalley Jan. 21, 2020, 4:25 p.m. UTC
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(-)

Comments

Stephen Smalley Jan. 24, 2020, 1:30 p.m. UTC | #1
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 mbox series

Patch

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;