Re: sw_perf_event_destroy() oops while fuzzing

2013-04-13 Thread Tommi Rantala
2013/4/12 Tommi Rantala :
> 2013/4/12 Peter Zijlstra :
>> perf_swevent_init() only sets event->destroy() (to
>> sw_perf_event_destroy) _after_ it increments the static key thing and
>> enqueues (and allocates) the hash list stuff.
>>
>> Obviously something is funny, but I'm not seeing it.
>
> Might this help... ? (untested)

I can reproduce the bug on my machine with:

#include 
#include 
#include 

int main(void)
{
struct perf_event_attr attr = {
.type = PERF_TYPE_SOFTWARE,
.size = sizeof(struct perf_event_attr),
.config = 0x,
};

syscall(__NR_perf_event_open, , getpid(), -1, -1, 0);
return 0;
}

The patch below fixes the oops. I'll send it properly.

> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 59412d0..fff6420 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -5330,7 +5330,7 @@ static void sw_perf_event_destroy(struct
> perf_event *event)
>
>  static int perf_swevent_init(struct perf_event *event)
>  {
> -   int event_id = event->attr.config;
> +   u64 event_id = event->attr.config;
>
> if (event->attr.type != PERF_TYPE_SOFTWARE)
> return -ENOENT;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: sw_perf_event_destroy() oops while fuzzing

2013-04-13 Thread Tommi Rantala
2013/4/12 Tommi Rantala tt.rant...@gmail.com:
 2013/4/12 Peter Zijlstra a.p.zijls...@chello.nl:
 perf_swevent_init() only sets event-destroy() (to
 sw_perf_event_destroy) _after_ it increments the static key thing and
 enqueues (and allocates) the hash list stuff.

 Obviously something is funny, but I'm not seeing it.

 Might this help... ? (untested)

I can reproduce the bug on my machine with:

#include unistd.h
#include sys/syscall.h
#include linux/perf_event.h

int main(void)
{
struct perf_event_attr attr = {
.type = PERF_TYPE_SOFTWARE,
.size = sizeof(struct perf_event_attr),
.config = 0x,
};

syscall(__NR_perf_event_open, attr, getpid(), -1, -1, 0);
return 0;
}

The patch below fixes the oops. I'll send it properly.

 diff --git a/kernel/events/core.c b/kernel/events/core.c
 index 59412d0..fff6420 100644
 --- a/kernel/events/core.c
 +++ b/kernel/events/core.c
 @@ -5330,7 +5330,7 @@ static void sw_perf_event_destroy(struct
 perf_event *event)

  static int perf_swevent_init(struct perf_event *event)
  {
 -   int event_id = event-attr.config;
 +   u64 event_id = event-attr.config;

 if (event-attr.type != PERF_TYPE_SOFTWARE)
 return -ENOENT;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: sw_perf_event_destroy() oops while fuzzing

2013-04-12 Thread Tommi Rantala
2013/4/12 Peter Zijlstra :
> On Fri, 2013-04-12 at 08:34 +0300, Tommi Rantala wrote:
>
>> [92759.011005] RIP  [] sw_perf_event_destroy+0x30/0x90
>
>> [114607.070003] RIP: 0010:[]  []
>> sw_perf_event_destroy+0x30/0x90
>
>> [114607.070003] RIP  [] sw_perf_event_destroy+0x30/0x90
>
> Would you have a source line for me that goes with that.. I can't seem
> to poke any holes just by looking.

It is crashing at:
   0x811a7200 <+48>:lock decl -0x7c3c9680(,%r12,4)

Matching source line is:
static_key_slow_dec(_swevent_enabled[event_id]);

-0x7c3c9680 is the address of perf_swevent_enabled[],
and %r12 is 0xff4c in the first oops.

So it looks like event_id is invalid.

(gdb) disassemble sw_perf_event_destroy
Dump of assembler code for function sw_perf_event_destroy:
   0x811a71d0 <+0>: push   %rbp
   0x811a71d1 <+1>: mov%rsp,%rbp
   0x811a71d4 <+4>: push   %r12
   0x811a71d6 <+6>: push   %rbx
   0x811a71d7 <+7>: cmpq   $0x0,0x288(%rdi)
   0x811a71df <+15>:mov%rdi,%rbx
   0x811a71e2 <+18>:mov0xa8(%rdi),%r12
   0x811a71e9 <+25>:je 0x811a7200

   0x811a71eb <+27>:mov$0x14cd,%esi
   0x811a71f0 <+32>:mov$0x829c3e50,%rdi
   0x811a71f7 <+39>:callq  0x810f0b10 
   0x811a71fc <+44>:nopl   0x0(%rax)
   0x811a7200 <+48>:lock decl -0x7c3c9680(,%r12,4)
   0x811a7209 <+57>:mov0x294(%rbx),%edi
   0x811a720f <+63>:cmp$0x,%edi
   0x811a7212 <+66>:jne0x811a7220

   0x811a7214 <+68>:mov0x127ea5d(%rip),%r12#
0x82425c78 
   0x811a721b <+75>:mov%edi,%ebx
   0x811a721d <+77>:jmp0x811a7237

   0x811a721f <+79>:nop
   0x811a7220 <+80>:callq  0x811a7170

   0x811a7225 <+85>:jmp0x811a7254

   0x811a7227 <+87>:nopw   0x0(%rax,%rax,1)
   0x811a7230 <+96>:mov%eax,%edi
   0x811a7232 <+98>:callq  0x811a7170

   0x811a7237 <+103>:   add$0x1,%ebx
   0x811a723a <+106>:   mov$0x40,%esi
   0x811a723f <+111>:   mov%r12,%rdi
   0x811a7242 <+114>:   movslq %ebx,%rdx
   0x811a7245 <+117>:   callq  0x814c63f0

   0x811a724a <+122>:   cmp0x1c6d9f4(%rip),%eax#
0x82e14c44 
   0x811a7250 <+128>:   mov%eax,%ebx
   0x811a7252 <+130>:   jl 0x811a7230

   0x811a7254 <+132>:   pop%rbx
   0x811a7255 <+133>:   pop%r12
   0x811a7257 <+135>:   pop%rbp
   0x811a7258 <+136>:   retq
End of assembler dump.

(gdb) list *0x811a7200
0x811a7200 is in sw_perf_event_destroy
(/home/ttrantal/git/linux/arch/x86/include/asm/atomic.h:107).
102  *
103  * Atomically decrements @v by 1.
104  */
105 static inline void atomic_dec(atomic_t *v)
106 {
107 asm volatile(LOCK_PREFIX "decl %0"
108  : "+m" (v->counter));
109 }
110
111 /**

(gdb) print _swevent_enabled
$2 = (struct static_key (*)[9]) 0x83c36980 

> perf_swevent_init() only sets event->destroy() (to
> sw_perf_event_destroy) _after_ it increments the static key thing and
> enqueues (and allocates) the hash list stuff.
>
> Obviously something is funny, but I'm not seeing it.

Might this help... ? (untested)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 59412d0..fff6420 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5330,7 +5330,7 @@ static void sw_perf_event_destroy(struct
perf_event *event)

 static int perf_swevent_init(struct perf_event *event)
 {
-   int event_id = event->attr.config;
+   u64 event_id = event->attr.config;

if (event->attr.type != PERF_TYPE_SOFTWARE)
return -ENOENT;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: sw_perf_event_destroy() oops while fuzzing

2013-04-12 Thread Peter Zijlstra
On Fri, 2013-04-12 at 08:34 +0300, Tommi Rantala wrote:

> [92759.011005] RIP  [] sw_perf_event_destroy+0x30/0x90

> [114607.070003] RIP: 0010:[]  []
> sw_perf_event_destroy+0x30/0x90

> [114607.070003] RIP  [] sw_perf_event_destroy+0x30/0x90

Would you have a source line for me that goes with that.. I can't seem
to poke any holes just by looking.

perf_swevent_init() only sets event->destroy() (to
sw_perf_event_destroy) _after_ it increments the static key thing and
enqueues (and allocates) the hash list stuff.

Obviously something is funny, but I'm not seeing it.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: sw_perf_event_destroy() oops while fuzzing

2013-04-12 Thread Peter Zijlstra
On Fri, 2013-04-12 at 08:34 +0300, Tommi Rantala wrote:

 [92759.011005] RIP  [811a7200] sw_perf_event_destroy+0x30/0x90

 [114607.070003] RIP: 0010:[811a7200]  [811a7200]
 sw_perf_event_destroy+0x30/0x90

 [114607.070003] RIP  [811a7200] sw_perf_event_destroy+0x30/0x90

Would you have a source line for me that goes with that.. I can't seem
to poke any holes just by looking.

perf_swevent_init() only sets event-destroy() (to
sw_perf_event_destroy) _after_ it increments the static key thing and
enqueues (and allocates) the hash list stuff.

Obviously something is funny, but I'm not seeing it.

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: sw_perf_event_destroy() oops while fuzzing

2013-04-12 Thread Tommi Rantala
2013/4/12 Peter Zijlstra a.p.zijls...@chello.nl:
 On Fri, 2013-04-12 at 08:34 +0300, Tommi Rantala wrote:

 [92759.011005] RIP  [811a7200] sw_perf_event_destroy+0x30/0x90

 [114607.070003] RIP: 0010:[811a7200]  [811a7200]
 sw_perf_event_destroy+0x30/0x90

 [114607.070003] RIP  [811a7200] sw_perf_event_destroy+0x30/0x90

 Would you have a source line for me that goes with that.. I can't seem
 to poke any holes just by looking.

It is crashing at:
   0x811a7200 +48:lock decl -0x7c3c9680(,%r12,4)

Matching source line is:
static_key_slow_dec(perf_swevent_enabled[event_id]);

-0x7c3c9680 is the address of perf_swevent_enabled[],
and %r12 is 0xff4c in the first oops.

So it looks like event_id is invalid.

(gdb) disassemble sw_perf_event_destroy
Dump of assembler code for function sw_perf_event_destroy:
   0x811a71d0 +0: push   %rbp
   0x811a71d1 +1: mov%rsp,%rbp
   0x811a71d4 +4: push   %r12
   0x811a71d6 +6: push   %rbx
   0x811a71d7 +7: cmpq   $0x0,0x288(%rdi)
   0x811a71df +15:mov%rdi,%rbx
   0x811a71e2 +18:mov0xa8(%rdi),%r12
   0x811a71e9 +25:je 0x811a7200
sw_perf_event_destroy+48
   0x811a71eb +27:mov$0x14cd,%esi
   0x811a71f0 +32:mov$0x829c3e50,%rdi
   0x811a71f7 +39:callq  0x810f0b10 warn_slowpath_null
   0x811a71fc +44:nopl   0x0(%rax)
   0x811a7200 +48:lock decl -0x7c3c9680(,%r12,4)
   0x811a7209 +57:mov0x294(%rbx),%edi
   0x811a720f +63:cmp$0x,%edi
   0x811a7212 +66:jne0x811a7220
sw_perf_event_destroy+80
   0x811a7214 +68:mov0x127ea5d(%rip),%r12#
0x82425c78 cpu_possible_mask
   0x811a721b +75:mov%edi,%ebx
   0x811a721d +77:jmp0x811a7237
sw_perf_event_destroy+103
   0x811a721f +79:nop
   0x811a7220 +80:callq  0x811a7170
swevent_hlist_put_cpu
   0x811a7225 +85:jmp0x811a7254
sw_perf_event_destroy+132
   0x811a7227 +87:nopw   0x0(%rax,%rax,1)
   0x811a7230 +96:mov%eax,%edi
   0x811a7232 +98:callq  0x811a7170
swevent_hlist_put_cpu
   0x811a7237 +103:   add$0x1,%ebx
   0x811a723a +106:   mov$0x40,%esi
   0x811a723f +111:   mov%r12,%rdi
   0x811a7242 +114:   movslq %ebx,%rdx
   0x811a7245 +117:   callq  0x814c63f0
find_next_bit
   0x811a724a +122:   cmp0x1c6d9f4(%rip),%eax#
0x82e14c44 nr_cpu_ids
   0x811a7250 +128:   mov%eax,%ebx
   0x811a7252 +130:   jl 0x811a7230
sw_perf_event_destroy+96
   0x811a7254 +132:   pop%rbx
   0x811a7255 +133:   pop%r12
   0x811a7257 +135:   pop%rbp
   0x811a7258 +136:   retq
End of assembler dump.

(gdb) list *0x811a7200
0x811a7200 is in sw_perf_event_destroy
(/home/ttrantal/git/linux/arch/x86/include/asm/atomic.h:107).
102  *
103  * Atomically decrements @v by 1.
104  */
105 static inline void atomic_dec(atomic_t *v)
106 {
107 asm volatile(LOCK_PREFIX decl %0
108  : +m (v-counter));
109 }
110
111 /**

(gdb) print perf_swevent_enabled
$2 = (struct static_key (*)[9]) 0x83c36980 perf_swevent_enabled

 perf_swevent_init() only sets event-destroy() (to
 sw_perf_event_destroy) _after_ it increments the static key thing and
 enqueues (and allocates) the hash list stuff.

 Obviously something is funny, but I'm not seeing it.

Might this help... ? (untested)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 59412d0..fff6420 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -5330,7 +5330,7 @@ static void sw_perf_event_destroy(struct
perf_event *event)

 static int perf_swevent_init(struct perf_event *event)
 {
-   int event_id = event-attr.config;
+   u64 event_id = event-attr.config;

if (event-attr.type != PERF_TYPE_SOFTWARE)
return -ENOENT;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/