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
}