> On 11/12/19 8:08 AM, Christian Göttsche wrote: > While trying to confine systemd-shutdown, I am unable to see any > SELinux denials late at shutdown. > I tested on Debian sid with systemd 242/243 and Linux 4.19.67-2/5.3.9-1. > The command line is: `BOOT_IMAGE=/boot/vmlinuz-5.3.0-2-amd64 > root=UUID=0a22bd66-a082-4b76-b96b-ca5cff3ffdf6 ro security=selinux > console=ttyS0 console=tty0 log_buf_len=1M printk.devkmsg=on`. > When running poweroff or reboot, systemd-shutdown stalls but no denial > is printed. > With a script like [1] dmesg does not print any information. > In permissive mode the system powers off/reboots, but no denials are > printed. > Trying to stop auditd/systemd-journald beforehand does not help. > > Does the kernel itself shuts down the ring buffer, or can systemd > interfere somehow? For the record: With a custom kernel I was able to retrieve the denials and confine systemd-shutdown. --- security/selinux/avc.c | 58 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index d18cb32a242a..26c440f022ce 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -751,6 +751,62 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) } } +static void dump_avc_to_console(const struct selinux_audit_data *sad) +{ + u32 av = sad->audited; + char perm_str[128]; + const char **perms; + int i, perm; + char *scontext = NULL, *tcontext = NULL; + u32 context_len; + + if (av == 0) { + snprintf(perm_str, sizeof(perm_str), " null"); + } else { + perms = secclass_map[sad->tclass-1].perms; + + snprintf(perm_str, sizeof(perm_str), " {"); + + i = 0; + perm = 1; + + while (i < (sizeof(av) * 8)) { + if ((perm & av) && perms[i]) { + strncat(perm_str, " ", + sizeof(perm_str) - strlen(perm_str) + - 1); + strncat(perm_str, perms[i], + sizeof(perm_str) - strlen(perm_str) + - 1); + av &= ~perm; + } + i++; + perm <<= 1; + } + + if (av) + strncat(perm_str, " UNKNOWN", + sizeof(perm_str) - strlen(perm_str) - 1); + + strncat(perm_str, " }", sizeof(perm_str) - strlen(perm_str) + - 1); + } + + security_sid_to_context(sad->state, sad->ssid, &scontext, &context_len); + security_sid_to_context(sad->state, sad->tsid, &tcontext, &context_len); + + pr_warn("SELinux avc: %s %s for scontext=%s tcontext=%s tclass=%s permissive=%d\n", + sad->denied ? "denied" : "granted", + perm_str, + scontext ? scontext : "KERNEL SID", + tcontext ? tcontext : "KERNEL SID", + secclass_map[sad->tclass-1].name, + sad->denied ? (sad->result ? 0 : 1) : -1); + + kfree(scontext); + kfree(tcontext); +} + /* This is the slow part of avc audit with big stack footprint */ noinline int slow_avc_audit(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, @@ -779,6 +835,8 @@ noinline int slow_avc_audit(struct selinux_state *state, a->selinux_audit_data = &sad; + dump_avc_to_console(&sad); + common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback); return 0; } -- 2.25.1