lkml.org 
[lkml]   [2014]   [Feb]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: perf_fuzzer compiled for x32 causes reboot
On 02/24/2014 09:32 AM, Vince Weaver wrote:
>>
>> Peter, does x32 have a slightly different ABI/calling convention that
>> would make any of these patches just slightly 'off'?
>
> I do note that
> perf_callchain_user();
>
> Does
> fp = (void __user *)regs->bp;
>
> ...
>
> bytes = copy_from_user_nmi(&frame, fp, sizeof(frame));
>
>
> And in my particular executable RBP has nothing to do with a frame
> pointer, but is instead being used as a general purpose register.
>
> Am I missing something here? Though in that case I'm not sure why this
> wouldn't be easier to trigger.
>

Neither x86-64 nor x32 are typically compiled with fixed frame pointers
(which would be %rbp if they are). So I'm guessing the perf_callchain
logic is only applicable to a user-space binary explicitly compiled with
frame pointers turned on.

So copy_from_user_nmi() stumbles onto a nonexistent page and takes a
page fault. This isn't a big deal, because perf_callchain_user() is set
up to handle that (and just terminates the trace), *except* now CR2 is
corrupt, and we took this event while handling a page fault already...
and apparently before we even did read_cr2() in __do_page_fault.

The description of copy_from_user_nmi() states:

/*
* We rely on the nested NMI work to allow atomic faults from the NMI
path; the
* nested NMI paths are careful to preserve CR2.
*/

... but that doesn't seem to happen here for whatever reason.

There is no hint in your trace what happens after the kernel page fault
so that makes it hard to know.

-hpa



\
 
 \ /
  Last update: 2014-02-24 19:21    [W:0.256 / U:0.192 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site