[oss-security] CVE-2020-10708 kernel: race condition in kernel/audit.c may allow low privilege users trigger kernel panic

Richard Guy Briggs rgb at redhat.com
Fri Apr 17 15:29:52 UTC 2020


On 2020-04-17 10:03, Paul Moore wrote:
> On Fri, Apr 17, 2020 at 9:39 AM Steve Grubb <sgrubb at redhat.com> wrote:
> > Hello,
> >
> > Since this is public...no harm dropping a copy over here. My thoughts are
> > that there is a race here. But since starting/stopping the audit daemon
> > requires root privs and as root you can do worse things. I don't know if this
> > is fixable or working per design.
> 
> The first thing to note is that the code snippets below are not from a
> modern upstream kernel; I'm guessing it's a RHEL-7.x based kernel
> given the problem report.

That would be correct.

>  The relevant code changed substantially
> when I reworked how the audit queue was managed; it's been a while now
> so I can't say with 100% confidence that this has been sorted out, but
> I believe the current upstream code should handle auditd restarts
> within the bounds of the record queue.

The upstream code has already been tested and has withstood this sort of
abuse for a sustained period of testing time.  It is believed that
commit 5b52330bbfe6 ("audit: fix auditd/kernel connection state
tracking") solved this issue.

> Ultimately if you configure the system to panic when you start
> dropping audit records, and you stop the audit daemon for a period of
> time such that the queues start to overflow, the system will panic.
> That's what you have configured it to do :)
> 
> It is also important to note that the panic-on-overflow behavior is
> not the default, the sysadmin must explicitly configure the system to
> behave in this way.

What Paul said.  :-)

> > ----------  Forwarded Message  ----------
> >
> > Subject: [oss-security] CVE-2020-10708 kernel: race condition in kernel/
> > audit.c may allow low privilege users trigger kernel panic
> > Date: Friday, April 17, 2020, 12:40:10 AM EDT
> > From: 陈伟宸(田各) <splendidsky.cwc at alibaba-inc.com>
> > To: oss-security <oss-security at lists.openwall.com>
> >
> >
> > "A race condition was found in the Linux kernel audit subsystem. When the
> > system is configured to panic on events being dropped, an attacker who is able
> > to trigger an audit event that starts while auditd is in the process of
> > starting may be able to cause the system to panic by exploiting a race
> > condition in audit event handling. This creates a denial of service by
> > causing a panic."
> >
> > https://bugzilla.redhat.com/show_bug.cgi?id=1822593
> >
> > Env:
> >     Red Hat Enterprise Linux Server release 7.7 (Maipo)
> >     3.10.0-1062.12.1.el7.x86_64
> >
> > Details:
> > 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 attackers to trigger kernel panic.
> > Here is panic call stack:
> >
> >
> > 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;
> >     }
> > }
> >
> > How to reproduce:
> > 1. set audit-failure to AUDIT_FAIL_PANIC(2) and add a random audit rule like:
> > [root at test ~]# cat /etc/audit/rules.d/audit.rules
> > -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
> >
> > Thanks.
> 
> paul moore

- RGB

--
Richard Guy Briggs <rgb at redhat.com>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635




More information about the Linux-audit mailing list