]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
selinux: reload label db on policy load with libselinux 3.2
authorChristian Göttsche <cgzones@googlemail.com>
Fri, 14 May 2021 12:12:39 +0000 (14:12 +0200)
committerChristian Göttsche <cgzones@googlemail.com>
Fri, 14 May 2021 12:12:39 +0000 (14:12 +0200)
Currently the label database is not reloaded with libselinux 3.2 on a
policy reload.

Since libselinux 3.2 avc_open(3) uses the SELinux status page instead of
a netlink socket to check for policy reloads.
The status page is also queried in mac_selinux_maybe_reload().
Thus calls to selinux_check_access(3) might consume an update, queried
by selinux_status_updated(3), leaving mac_selinux_maybe_reload() unable
to detect a policy reload.

Do not use selinux_status_updated(3), use selinux_status_policyload(3)
unconditionally.

Relevant libselinux commit: https://github.com/SELinuxProject/selinux/commit/05bdc03130d741e53e1fb45a958d0a2c184be503

Debian Bullseye is going to ship libselinux 3.1, so stay compatible for
backports.

src/basic/selinux-util.c

index 8c5544d46bbbda4efe954c4a1d9f5bb05ae0842a..0af541d0b1909e588dad5d29727558341a1c6f2c 100644 (file)
@@ -182,28 +182,27 @@ int mac_selinux_init(void) {
 
 void mac_selinux_maybe_reload(void) {
 #if HAVE_SELINUX
-        int r;
+        int policyload;
 
         if (!initialized)
                 return;
 
-        r = selinux_status_updated();
-        if (r < 0)
-                log_debug_errno(errno, "Failed to update SELinux from status page: %m");
-        if (r > 0) {
-                int policyload;
-
-                log_debug("SELinux status page update");
-
-                /* from libselinux > 3.1 callbacks gets automatically called, see
-                   https://github.com/SELinuxProject/selinux/commit/05bdc03130d741e53e1fb45a958d0a2c184be503 */
+        /* Do not use selinux_status_updated(3), cause since libselinux 3.2 selinux_check_access(3),
+         * called in core and user instances, does also use it under the hood.
+         * That can cause changes to be consumed by selinux_check_access(3) and not being visible here.
+         * Also do not use selinux callbacks, selinux_set_callback(3), cause they are only automatically
+         * invoked since libselinux 3.2 by selinux_status_updated(3).
+         * Relevant libselinux commit: https://github.com/SELinuxProject/selinux/commit/05bdc03130d741e53e1fb45a958d0a2c184be503
+         * Debian Bullseye is going to ship libselinux 3.1, so stay compatible for backports. */
+        policyload = selinux_status_policyload();
+        if (policyload < 0) {
+                log_debug_errno(errno, "Failed to get SELinux policyload from status page: %m");
+                return;
+        }
 
-                /* only reload on policy changes, not enforcing status changes */
-                policyload = selinux_status_policyload();
-                if (policyload != last_policyload) {
-                        mac_selinux_reload(policyload);
-                        last_policyload = policyload;
-                }
+        if (policyload != last_policyload) {
+                mac_selinux_reload(policyload);
+                last_policyload = policyload;
         }
 #endif
 }