From: Christian Göttsche Date: Fri, 14 May 2021 12:12:39 +0000 (+0200) Subject: selinux: reload label db on policy load with libselinux 3.2 X-Git-Tag: v249-rc1~186^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c46c76881144271b9a18842e086d1318febdb372;p=thirdparty%2Fsystemd.git selinux: reload label db on policy load with libselinux 3.2 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. --- diff --git a/src/basic/selinux-util.c b/src/basic/selinux-util.c index 8c5544d46bb..0af541d0b19 100644 --- a/src/basic/selinux-util.c +++ b/src/basic/selinux-util.c @@ -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 }