lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20170123170442.GL6515@twins.programming.kicks-ass.net>
Date:   Mon, 23 Jan 2017 18:04:42 +0100
From:   Peter Zijlstra <peterz@...radead.org>
To:     Dmitry Vyukov <dvyukov@...gle.com>
Cc:     Ingo Molnar <mingo@...hat.com>,
        Arnaldo Carvalho de Melo <acme@...nel.org>,
        Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
        LKML <linux-kernel@...r.kernel.org>,
        syzkaller <syzkaller@...glegroups.com>
Subject: Re: perf: use-after-free in perf_event_for_each

On Mon, Jan 23, 2017 at 02:30:12PM +0100, Dmitry Vyukov wrote:
> Hello,
> 
> The following program triggers use-after-free in perf_event_for_each:
> https://gist.githubusercontent.com/dvyukov/f1c354a8356e42f4d0b3d912e1bec956/raw/31d7ecdf6dc2c7327b80ef8581a39c823bbe405d/gistfile1.txt
> 
> BUG: KASAN: use-after-free in perf_event_for_each_child+0x15f/0x180
> kernel/events/core.c:4495 at addr ffff8800680ec248
> Read of size 8 by task a.out/19370
> CPU: 3 PID: 19370 Comm: a.out Not tainted 4.10.0-rc5+ #186
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> Call Trace:
>  __asan_report_load8_noabort+0x3e/0x40 mm/kasan/report.c:328
>  perf_event_for_each_child+0x15f/0x180 kernel/events/core.c:4495

That's the WARN_ON_ONCE() in there, and since the object that's being
UAF'ed is an event, this would be the first dereference in there, this
means that this is the event passed in from the next function.

>  perf_event_for_each kernel/events/core.c:4514 [inline]

And this is the first caller (ie, !sibling), suggesting that the line
above:

  event = event->group_leader;

is the curlprit, because the earlier event->ctx, dereference is fine
(and we're holding ctx->mutex).


>  _perf_ioctl kernel/events/core.c:4671 [inline]
>  perf_ioctl+0x9b5/0x1480 kernel/events/core.c:4685
>  vfs_ioctl fs/ioctl.c:43 [inline]


This also matches with that the program does; which is something along
the lines of:

  event = sys_perf_event_open();
  sibling = sys_perf_event_open(.group_fd = event);
  dup3(sibling, event, ..);
  ioctl(sibling);

Where the dup3() will close event (which should then promote the sibling
to its own full event) and ioctl() on the sibling, which them comes
apart.


So it looks like something fishy on the close the leader and promote the
sibling code, but I cannot put my finger on it just yet. I've ran out of
time for today, but will continue staring at this tomorrow -- of course
hoping that this email will give someone else ideas while I'm off :-)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ