View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0017204 | CentOS-7 | kernel | public | 2020-03-31 05:41 | 2020-03-31 05:58 |
Reporter | tiange | Assigned To | |||
Priority | high | Severity | block | Reproducibility | always |
Status | new | Resolution | open | ||
OS Version | 3.10.0-1062.18.1 | ||||
Product Version | 7.6.1810 | ||||
Summary | 0017204: audit.c - race condition may allow low privilege users trigger kernel panic | ||||
Description | Function audit_log_end and audit_panic may have race conditions when auditd is restarting because audit_pid can be NULL in audit_log_end and then become not NULL in audit_panic, which may allow low privilege users to trigger kernel panic. call track: [ 70.184291] [<ffffffff8a37b416>] dump_stack+0x19/0x1b [ 70.184764] [<ffffffff8a374a0b>] panic+0xe8/0x21f [ 70.185228] [<ffffffff89d362e4>] audit_panic+0x64/0x70 [ 70.185708] [<ffffffff89d3632f>] audit_log_lost+0x3f/0xd0 [ 70.186234] [<ffffffff89d3653c>] audit_printk_skb+0x3c/0x70 [ 70.186751] [<ffffffff89d36792>] audit_log_end+0x42/0x110 [ 70.187278] [<ffffffff89d3be6a>] audit_log_exit+0x26a/0x970 [ 70.187798] [<ffffffff89d3df5a>] ? audit_filter_inodes+0xda/0x130 [ 70.188384] [<ffffffff89d3e67d>] __audit_syscall_exit+0x21d/0x280 [ 70.188970] [<ffffffff8a38e0c2>] sysret_audit+0x17/0x21 void audit_log_end(struct audit_buffer *ab) { if (!ab) return; if (!audit_rate_check()) { audit_log_lost("rate limit exceeded"); } else { struct nlmsghdr *nlh = nlmsg_hdr(ab->skb); nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN; if (audit_pid) { skb_queue_tail(&audit_skb_queue, ab->skb); wake_up_interruptible(&kauditd_wait); } else { audit_printk_skb(ab->skb); // <- audit_pid == NULL when auditd is killed } ab->skb = NULL; } audit_buffer_free(ab); } -> audit_printk_skb -> audit_log_lost -> void audit_panic(const char *message) { switch (audit_failure) { case AUDIT_FAIL_SILENT: break; case AUDIT_FAIL_PRINTK: if (printk_ratelimit()) printk(KERN_ERR "audit: %s\n", message); break; case AUDIT_FAIL_PANIC: /* test audit_pid since printk is always losey, why bother? */ if (audit_pid) // <- audit_pid not NULL because auditd is restarting panic("audit: %s\n", message); break; } } | ||||
Steps To Reproduce | 1. set audit-failure to AUDIT_FAIL_PANIC(2) and add a random audit rule like: [root@test ~]# cat /etc/audit/audit.rules ## This file is automatically generated from /etc/audit/rules.d -D -b 8192 -f 2 -w /etc/hosts -p rwa -k hosts 2. keep killing auditd and then starting auditd, for example: while true; do ps aux | grep "/sbin/auditd" | grep -v "grep" | awk '{print $2}' | xargs kill; service auditd start; systemctl reset-failed auditd.service; done 3. log in a low privilege user and keep reading /etc/hosts, for example: while true; do cat /etc/hosts > /dev/null; done 4. kernel panic will happen within several minutes | ||||
Additional Information | panic call track: [ 70.181339] Kernel panic - not syncing: audit: printk limit exceeded [ 70.182417] CPU: 1 PID: 11058 Comm: cat Kdump: loaded Not tainted 3.10.0-1062.18.1.el7.x86_64 #1 [ 70.183335] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS 8c24b4c 04/01/2014 [ 70.184048] Call Trace: [ 70.184291] [<ffffffff8a37b416>] dump_stack+0x19/0x1b [ 70.184764] [<ffffffff8a374a0b>] panic+0xe8/0x21f [ 70.185228] [<ffffffff89d362e4>] audit_panic+0x64/0x70 [ 70.185708] [<ffffffff89d3632f>] audit_log_lost+0x3f/0xd0 [ 70.186234] [<ffffffff89d3653c>] audit_printk_skb+0x3c/0x70 [ 70.186751] [<ffffffff89d36792>] audit_log_end+0x42/0x110 [ 70.187278] [<ffffffff89d3be6a>] audit_log_exit+0x26a/0x970 [ 70.187798] [<ffffffff89d3df5a>] ? audit_filter_inodes+0xda/0x130 [ 70.188384] [<ffffffff89d3e67d>] __audit_syscall_exit+0x21d/0x280 [ 70.188970] [<ffffffff8a38e0c2>] sysret_audit+0x17/0x21 | ||||
Tags | No tags attached. | ||||
abrt_hash | |||||
URL | |||||
Date Modified | Username | Field | Change |
---|---|---|---|
2020-03-31 05:41 | tiange | New Issue |