View Issue Details

IDProjectCategoryView StatusLast Update
0017204CentOS-7kernelpublic2020-03-31 05:58
Reportertiange 
PriorityhighSeverityblockReproducibilityalways
Status newResolutionopen 
PlatformOSOS Version3.10.0-1062.18.1
Product Version7.6.1810 
Target VersionFixed in Version 
Summary0017204: audit.c - race condition may allow low privilege users trigger kernel panic
DescriptionFunction 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 Reproduce1. 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 Informationpanic 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
TagsNo tags attached.
abrt_hash
URL

Activities

There are no notes attached to this issue.

Issue History

Date Modified Username Field Change
2020-03-31 05:41 tiange New Issue