[meta-selinux][dunfell][PATCH] libselinux: Backport class cache flushing patch from 3.1


Daniel Danner <daniel.danner@...>
 

This fixes a bug in libselinux that gets triggered by loading another
policy at runtime. Before this patch, the userspace class cache was not
flushed when a new policy was loaded. This led to SELinux-aware
processes performing invalid lookups if their lifecycle overlapped with
a policy load. Specifically, lookups performed by dbus-daemon would
yield invalid results due to using outdated class IDs in their query.
---
...t-flush_class_cache-call-it-on-polic.patch | 126 ++++++++++++++++++
recipes-security/selinux/libselinux_3.0.bb | 1 +
2 files changed, 127 insertions(+)
create mode 100644 recipes-security/selinux/libselinux/0001-libselinux-export-flush_class_cache-call-it-on-polic.patch

diff --git recipes-security/selinux/libselinux/0001-libselinux-export-flush_class_cache-call-it-on-polic.patch recipes-security/selinux/libselinux/0001-libselinux-export-flush_class_cache-call-it-on-polic.patch
new file mode 100644
index 0000000..dd79f64
--- /dev/null
+++ recipes-security/selinux/libselinux/0001-libselinux-export-flush_class_cache-call-it-on-polic.patch
@@ -0,0 +1,126 @@
+From 7bece3768b8ce63d79ef59bab83517b4e950f8fb Mon Sep 17 00:00:00 2001
+From: Stephen Smalley <sds@...>
+Date: Tue, 21 Jan 2020 11:18:22 -0500
+Subject: [PATCH] libselinux: export flush_class_cache(), call it on policyload
+
+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@...>
+---
+ 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(-)
+
+Upstream-Status: Backport [https://github.com/SELinuxProject/selinux/commit/7bece3768b8ce63d79ef59bab83517b4e950f8fb]
+
+diff --git libselinux/include/selinux/selinux.h libselinux/include/selinux/selinux.h
+index fe46e681..7922d96b 100644
+--- libselinux/include/selinux/selinux.h
++++ 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 libselinux/src/avc_internal.c libselinux/src/avc_internal.c
+index 49cecc96..568a3d92 100644
+--- libselinux/src/avc_internal.c
++++ 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 libselinux/src/checkAccess.c libselinux/src/checkAccess.c
+index 16bfcfb6..7227ffe5 100644
+--- libselinux/src/checkAccess.c
++++ 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 libselinux/src/selinux_internal.h libselinux/src/selinux_internal.h
+index 8b4bed2f..61b78aaa 100644
+--- libselinux/src/selinux_internal.h
++++ 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 libselinux/src/stringrep.c libselinux/src/stringrep.c
+index 4db95398..29757b75 100644
+--- libselinux/src/stringrep.c
++++ 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;
+--
+2.25.1
+
diff --git recipes-security/selinux/libselinux_3.0.bb recipes-security/selinux/libselinux_3.0.bb
index 05d2346..17a25a9 100644
--- recipes-security/selinux/libselinux_3.0.bb
+++ recipes-security/selinux/libselinux_3.0.bb
@@ -12,4 +12,5 @@ SRC_URI += "\
file://libselinux-make-SOCK_CLOEXEC-optional.patch \
file://libselinux-define-FD_CLOEXEC-as-necessary.patch \
file://0001-Fix-building-against-musl-and-uClibc-libc-libraries.patch \
+ file://0001-libselinux-export-flush_class_cache-call-it-on-polic.patch \
"
--
2.25.1

Join {yocto@lists.yoctoproject.org to automatically receive all group messages.