All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty
@ 2015-04-07  9:31 He Kuang
  2015-04-07  9:31 ` [PATCH 2/2] perf trace: Fix segmentfault on perf trace He Kuang
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: He Kuang @ 2015-04-07  9:31 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, jolsa; +Cc: wangnan0, linux-kernel

perf_evlist__mmap_consume() uses perf_mmap__empty() to judge whether
perf_mmap is empty and can be released. But the result is inverted so
fix it.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/evlist.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 82bf224..76ef7ee 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -695,7 +695,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
 
 static bool perf_mmap__empty(struct perf_mmap *md)
 {
-	return perf_mmap__read_head(md) != md->prev;
+	return perf_mmap__read_head(md) == md->prev;
 }
 
 static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx)
-- 
2.3.3.220.g9ab698f


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/2] perf trace: Fix segmentfault on perf trace
  2015-04-07  9:31 [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty He Kuang
@ 2015-04-07  9:31 ` He Kuang
  2015-04-07 12:36   ` Arnaldo Carvalho de Melo
  2015-04-07 11:59 ` [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty Arnaldo Carvalho de Melo
  2015-04-08 15:10 ` [tip:perf/core] " tip-bot for He Kuang
  2 siblings, 1 reply; 9+ messages in thread
From: He Kuang @ 2015-04-07  9:31 UTC (permalink / raw)
  To: acme, a.p.zijlstra, mingo, jolsa; +Cc: wangnan0, linux-kernel

After perf_evlist__filter_pollfd() filters out fds and releases
perf_mmap by using perf_evlist__mmap_put(), refcnt of perf_mmap hits 1
then perf_evlist__mmap_consume() will do the final unmap. In this
condition, perf_evlist__mmap_read() will crash by referencing invalid
mmap. Put refcnt check before use.

Can be reproduced as following:

  $ perf trace --duration 1.0 ls
    ...
    perf: Segmentation fault
    Obtained 14 stack frames.
    ./perf(dump_stack+0x2e) [0x503c2d]
    ./perf(sighandler_dump_stack+0x2e)
    [0x503d0c]
    /lib64/libc.so.6(+0x34df0) [0x7f5fd9a4adf0]
    ./perf() [0x4a8fda]
    ./perf(perf_evlist__mmap_read+0x56)
    [0x4aae93]
    ./perf() [0x470b28]
    ./perf(cmd_trace+0xada) [0x4727bd]
    ./perf() [0x49c4f4]
    ./perf() [0x49c74d]
    ./perf() [0x49c899]
    ./perf(main+0x23b)
    [0x49cbfa]
    /lib64/libc.so.6(__libc_start_main+0xf5)
    [0x7f5fd9a377b5]
    ./perf() [0x434ea5]
    [(nil)]

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/evlist.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 76ef7ee..9d36433 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -634,11 +634,18 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
 {
 	struct perf_mmap *md = &evlist->mmap[idx];
-	unsigned int head = perf_mmap__read_head(md);
-	unsigned int old = md->prev;
-	unsigned char *data = md->base + page_size;
+	unsigned int head;
+	unsigned int old;
+	unsigned char *data;
 	union perf_event *event = NULL;
 
+	if (md == NULL || md->refcnt == 0)
+		return NULL;
+
+	head = perf_mmap__read_head(md);
+	old = md->prev;
+	data = md->base + page_size;
+
 	if (evlist->overwrite) {
 		/*
 		 * If we're further behind than half the buffer, there's a chance
-- 
2.3.3.220.g9ab698f


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty
  2015-04-07  9:31 [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty He Kuang
  2015-04-07  9:31 ` [PATCH 2/2] perf trace: Fix segmentfault on perf trace He Kuang
@ 2015-04-07 11:59 ` Arnaldo Carvalho de Melo
  2015-04-08 15:10 ` [tip:perf/core] " tip-bot for He Kuang
  2 siblings, 0 replies; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-04-07 11:59 UTC (permalink / raw)
  To: He Kuang; +Cc: a.p.zijlstra, mingo, jolsa, wangnan0, linux-kernel

Em Tue, Apr 07, 2015 at 05:31:10PM +0800, He Kuang escreveu:
> perf_evlist__mmap_consume() uses perf_mmap__empty() to judge whether
> perf_mmap is empty and can be released. But the result is inverted so
> fix it.

> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> @@ -695,7 +695,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
>  
>  static bool perf_mmap__empty(struct perf_mmap *md)
>  {
> -	return perf_mmap__read_head(md) != md->prev;
> +	return perf_mmap__read_head(md) == md->prev;
>  }
>  
>  static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx)

Argh, thanks, good spotting, applying...

- Arnaldo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] perf trace: Fix segmentfault on perf trace
  2015-04-07  9:31 ` [PATCH 2/2] perf trace: Fix segmentfault on perf trace He Kuang
@ 2015-04-07 12:36   ` Arnaldo Carvalho de Melo
  2015-04-08  3:15     ` He Kuang
  0 siblings, 1 reply; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-04-07 12:36 UTC (permalink / raw)
  To: He Kuang; +Cc: a.p.zijlstra, mingo, jolsa, wangnan0, linux-kernel

Em Tue, Apr 07, 2015 at 05:31:11PM +0800, He Kuang escreveu:
> After perf_evlist__filter_pollfd() filters out fds and releases
> perf_mmap by using perf_evlist__mmap_put(), refcnt of perf_mmap hits 1
> then perf_evlist__mmap_consume() will do the final unmap. In this
> condition, perf_evlist__mmap_read() will crash by referencing invalid
> mmap. Put refcnt check before use.
> 
> Can be reproduced as following:

After applying 1/2 in this series and trying to reproduce I couldn't, it
works, looking at the code...

Let me get my head around this, idea was that after all fds associated
with a mmap would be closed, i.e. the perf_mmap->refcnt hits zero, then
we would have to drain whatever was left in the mmap, but looking again
that doesn't look like that is what is doing, becaue in filter_pollfd we
will munmap it before being able to "drain" it, as all mmaps were
closed, thus filter_pollfd returned zero...

Reading on, thanks for the patch!

- Arnaldo

 
>   $ perf trace --duration 1.0 ls
>     ...
>     perf: Segmentation fault
>     Obtained 14 stack frames.
>     ./perf(dump_stack+0x2e) [0x503c2d]
>     ./perf(sighandler_dump_stack+0x2e)
>     [0x503d0c]
>     /lib64/libc.so.6(+0x34df0) [0x7f5fd9a4adf0]
>     ./perf() [0x4a8fda]
>     ./perf(perf_evlist__mmap_read+0x56)
>     [0x4aae93]
>     ./perf() [0x470b28]
>     ./perf(cmd_trace+0xada) [0x4727bd]
>     ./perf() [0x49c4f4]
>     ./perf() [0x49c74d]
>     ./perf() [0x49c899]
>     ./perf(main+0x23b)
>     [0x49cbfa]
>     /lib64/libc.so.6(__libc_start_main+0xf5)
>     [0x7f5fd9a377b5]
>     ./perf() [0x434ea5]
>     [(nil)]
> 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/perf/util/evlist.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 76ef7ee..9d36433 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -634,11 +634,18 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
>  union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
>  {
>  	struct perf_mmap *md = &evlist->mmap[idx];
> -	unsigned int head = perf_mmap__read_head(md);
> -	unsigned int old = md->prev;
> -	unsigned char *data = md->base + page_size;
> +	unsigned int head;
> +	unsigned int old;
> +	unsigned char *data;
>  	union perf_event *event = NULL;
>  
> +	if (md == NULL || md->refcnt == 0)
> +		return NULL;
> +
> +	head = perf_mmap__read_head(md);
> +	old = md->prev;
> +	data = md->base + page_size;
> +
>  	if (evlist->overwrite) {
>  		/*
>  		 * If we're further behind than half the buffer, there's a chance
> -- 
> 2.3.3.220.g9ab698f

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] perf trace: Fix segmentfault on perf trace
  2015-04-07 12:36   ` Arnaldo Carvalho de Melo
@ 2015-04-08  3:15     ` He Kuang
  2015-05-11 12:11       ` He Kuang
  0 siblings, 1 reply; 9+ messages in thread
From: He Kuang @ 2015-04-08  3:15 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: a.p.zijlstra, mingo, jolsa, wangnan0, linux-kernel

Hi, Arnaldo
On 2015/4/7 20:36, Arnaldo Carvalho de Melo wrote:
> Em Tue, Apr 07, 2015 at 05:31:11PM +0800, He Kuang escreveu:
>> After perf_evlist__filter_pollfd() filters out fds and releases
>> perf_mmap by using perf_evlist__mmap_put(), refcnt of perf_mmap hits 1
>> then perf_evlist__mmap_consume() will do the final unmap. In this
>> condition, perf_evlist__mmap_read() will crash by referencing invalid
>> mmap. Put refcnt check before use.
>>
>> Can be reproduced as following:
> After applying 1/2 in this series and trying to reproduce I couldn't, it
> works, looking at the code...
>
> Let me get my head around this, idea was that after all fds associated
> with a mmap would be closed, i.e. the perf_mmap->refcnt hits zero, then
> we would have to drain whatever was left in the mmap, but looking again
> that doesn't look like that is what is doing, becaue in filter_pollfd we
> will munmap it before being able to "drain" it, as all mmaps were
> closed, thus filter_pollfd returned zero...

In function __perf_evlist__mmap(), refcnt is initialized to 2, see commit:
   823969860329 ("perf evlist: Refcount mmaps")

After filter_pollfd,  perf_mmap->refcnt is 1 not 0.

   perf_evlist__filter_pollfd()                     -- refcnt=1
   draining = true
   if (perf_evlist__mmap_read() != NULL)
           perf_evlist__mmap_consume()    -- unmap, refcnt = 0
           perf_evlist__mmap_read()            -- segfault
else
exit

I noticed that this issue also exists in builtin-record.c, but it
checks before mmap_read():

if (rec->evlist->mmap[i].base) {
         if (record__mmap_read(rec, i, draining) != 0) {

So we can either do the check outside
builtin-trace.c:perf_evlist__mmap_read() like what
builtin-record.c do or inside. What's your opinion?
>
> Reading on, thanks for the patch!
>
> - Arnaldo
>
>   
>>    $ perf trace --duration 1.0 ls
>>      ...
>>      perf: Segmentation fault
>>      Obtained 14 stack frames.
>>      ./perf(dump_stack+0x2e) [0x503c2d]
>>      ./perf(sighandler_dump_stack+0x2e)
>>      [0x503d0c]
>>      /lib64/libc.so.6(+0x34df0) [0x7f5fd9a4adf0]
>>      ./perf() [0x4a8fda]
>>      ./perf(perf_evlist__mmap_read+0x56)
>>      [0x4aae93]
>>      ./perf() [0x470b28]
>>      ./perf(cmd_trace+0xada) [0x4727bd]
>>      ./perf() [0x49c4f4]
>>      ./perf() [0x49c74d]
>>      ./perf() [0x49c899]
>>      ./perf(main+0x23b)
>>      [0x49cbfa]
>>      /lib64/libc.so.6(__libc_start_main+0xf5)
>>      [0x7f5fd9a377b5]
>>      ./perf() [0x434ea5]
>>      [(nil)]
>>
>> Signed-off-by: He Kuang <hekuang@huawei.com>
>> ---
>>   tools/perf/util/evlist.c | 13 ++++++++++---
>>   1 file changed, 10 insertions(+), 3 deletions(-)
>>
>> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
>> index 76ef7ee..9d36433 100644
>> --- a/tools/perf/util/evlist.c
>> +++ b/tools/perf/util/evlist.c
>> @@ -634,11 +634,18 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist,
>>   union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
>>   {
>>   	struct perf_mmap *md = &evlist->mmap[idx];
>> -	unsigned int head = perf_mmap__read_head(md);
>> -	unsigned int old = md->prev;
>> -	unsigned char *data = md->base + page_size;
>> +	unsigned int head;
>> +	unsigned int old;
>> +	unsigned char *data;
>>   	union perf_event *event = NULL;
>>   
>> +	if (md == NULL || md->refcnt == 0)
>> +		return NULL;
>> +
>> +	head = perf_mmap__read_head(md);
>> +	old = md->prev;
>> +	data = md->base + page_size;
>> +
>>   	if (evlist->overwrite) {
>>   		/*
>>   		 * If we're further behind than half the buffer, there's a chance
>> -- 
>> 2.3.3.220.g9ab698f
>



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [tip:perf/core] perf evlist: Fix inverted logic in perf_mmap__empty
  2015-04-07  9:31 [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty He Kuang
  2015-04-07  9:31 ` [PATCH 2/2] perf trace: Fix segmentfault on perf trace He Kuang
  2015-04-07 11:59 ` [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty Arnaldo Carvalho de Melo
@ 2015-04-08 15:10 ` tip-bot for He Kuang
  2 siblings, 0 replies; 9+ messages in thread
From: tip-bot for He Kuang @ 2015-04-08 15:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: wangnan0, tglx, jolsa, acme, mingo, linux-kernel, hpa,
	a.p.zijlstra, hekuang

Commit-ID:  8ea92ceb748535799e3e9f35afb85bdc23bf6d7c
Gitweb:     http://git.kernel.org/tip/8ea92ceb748535799e3e9f35afb85bdc23bf6d7c
Author:     He Kuang <hekuang@huawei.com>
AuthorDate: Tue, 7 Apr 2015 17:31:10 +0800
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 8 Apr 2015 09:06:58 -0300

perf evlist: Fix inverted logic in perf_mmap__empty

perf_evlist__mmap_consume() uses perf_mmap__empty() to judge whether
perf_mmap is empty and can be released. But the result is inverted so
fix it.

Signed-off-by: He Kuang <hekuang@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1428399071-7141-1-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/evlist.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 82bf224..76ef7ee 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -695,7 +695,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
 
 static bool perf_mmap__empty(struct perf_mmap *md)
 {
-	return perf_mmap__read_head(md) != md->prev;
+	return perf_mmap__read_head(md) == md->prev;
 }
 
 static void perf_evlist__mmap_get(struct perf_evlist *evlist, int idx)

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] perf trace: Fix segmentfault on perf trace
  2015-04-08  3:15     ` He Kuang
@ 2015-05-11 12:11       ` He Kuang
  2015-05-11 13:47         ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 9+ messages in thread
From: He Kuang @ 2015-05-11 12:11 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: a.p.zijlstra, mingo, jolsa, wangnan0, linux-kernel

Hi, Arnaldo

On 2015/4/8 11:15, He Kuang wrote:
> Hi, Arnaldo
> On 2015/4/7 20:36, Arnaldo Carvalho de Melo wrote:
>> Em Tue, Apr 07, 2015 at 05:31:11PM +0800, He Kuang escreveu:
>>> After perf_evlist__filter_pollfd() filters out fds and releases
>>> perf_mmap by using perf_evlist__mmap_put(), refcnt of perf_mmap hits 1
>>> then perf_evlist__mmap_consume() will do the final unmap. In this
>>> condition, perf_evlist__mmap_read() will crash by referencing invalid
>>> mmap. Put refcnt check before use.
>>>
>>> Can be reproduced as following:
>> After applying 1/2 in this series and trying to reproduce I couldn't, it
>> works, looking at the code...
>>
>> Let me get my head around this, idea was that after all fds associated
>> with a mmap would be closed, i.e. the perf_mmap->refcnt hits zero, then
>> we would have to drain whatever was left in the mmap, but looking again
>> that doesn't look like that is what is doing, becaue in filter_pollfd we
>> will munmap it before being able to "drain" it, as all mmaps were
>> closed, thus filter_pollfd returned zero...
>
> In function __perf_evlist__mmap(), refcnt is initialized to 2, see 
> commit:
>   823969860329 ("perf evlist: Refcount mmaps")
>
> After filter_pollfd,  perf_mmap->refcnt is 1 not 0.
>
>   perf_evlist__filter_pollfd()                     -- refcnt=1
>   draining = true
>   if (perf_evlist__mmap_read() != NULL)
>           perf_evlist__mmap_consume()    -- unmap, refcnt = 0
>           perf_evlist__mmap_read()            -- segfault
> else
> exit
>
> I noticed that this issue also exists in builtin-record.c, but it
> checks before mmap_read():
>
> if (rec->evlist->mmap[i].base) {
>         if (record__mmap_read(rec, i, draining) != 0) {
>
> So we can either do the check outside
> builtin-trace.c:perf_evlist__mmap_read() like what
> builtin-record.c do or inside. What's your opinion?

I found the issue is still there, so ping...

>>
>> Reading on, thanks for the patch!
>>
>> - Arnaldo
>>
>>>    $ perf trace --duration 1.0 ls
>>>      ...
>>>      perf: Segmentation fault
>>>      Obtained 14 stack frames.
>>>      ./perf(dump_stack+0x2e) [0x503c2d]
>>>      ./perf(sighandler_dump_stack+0x2e)
>>>      [0x503d0c]
>>>      /lib64/libc.so.6(+0x34df0) [0x7f5fd9a4adf0]
>>>      ./perf() [0x4a8fda]
>>>      ./perf(perf_evlist__mmap_read+0x56)
>>>      [0x4aae93]
>>>      ./perf() [0x470b28]
>>>      ./perf(cmd_trace+0xada) [0x4727bd]
>>>      ./perf() [0x49c4f4]
>>>      ./perf() [0x49c74d]
>>>      ./perf() [0x49c899]
>>>      ./perf(main+0x23b)
>>>      [0x49cbfa]
>>>      /lib64/libc.so.6(__libc_start_main+0xf5)
>>>      [0x7f5fd9a377b5]
>>>      ./perf() [0x434ea5]
>>>      [(nil)]
>>>
>>> Signed-off-by: He Kuang <hekuang@huawei.com>
>>> ---
>>>   tools/perf/util/evlist.c | 13 ++++++++++---
>>>   1 file changed, 10 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
>>> index 76ef7ee..9d36433 100644
>>> --- a/tools/perf/util/evlist.c
>>> +++ b/tools/perf/util/evlist.c
>>> @@ -634,11 +634,18 @@ static struct perf_evsel 
>>> *perf_evlist__event2evsel(struct perf_evlist *evlist,
>>>   union perf_event *perf_evlist__mmap_read(struct perf_evlist 
>>> *evlist, int idx)
>>>   {
>>>       struct perf_mmap *md = &evlist->mmap[idx];
>>> -    unsigned int head = perf_mmap__read_head(md);
>>> -    unsigned int old = md->prev;
>>> -    unsigned char *data = md->base + page_size;
>>> +    unsigned int head;
>>> +    unsigned int old;
>>> +    unsigned char *data;
>>>       union perf_event *event = NULL;
>>>   +    if (md == NULL || md->refcnt == 0)
>>> +        return NULL;
>>> +
>>> +    head = perf_mmap__read_head(md);
>>> +    old = md->prev;
>>> +    data = md->base + page_size;
>>> +
>>>       if (evlist->overwrite) {
>>>           /*
>>>            * If we're further behind than half the buffer, there's a 
>>> chance
>>> -- 
>>> 2.3.3.220.g9ab698f
>>
>
>



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] perf trace: Fix segmentfault on perf trace
  2015-05-11 12:11       ` He Kuang
@ 2015-05-11 13:47         ` Arnaldo Carvalho de Melo
  2015-05-11 13:57           ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-05-11 13:47 UTC (permalink / raw)
  To: He Kuang; +Cc: a.p.zijlstra, mingo, jolsa, wangnan0, linux-kernel

Em Mon, May 11, 2015 at 08:11:14PM +0800, He Kuang escreveu:
> Hi, Arnaldo
> 
> On 2015/4/8 11:15, He Kuang wrote:
> >Hi, Arnaldo
> >On 2015/4/7 20:36, Arnaldo Carvalho de Melo wrote:
> >>Em Tue, Apr 07, 2015 at 05:31:11PM +0800, He Kuang escreveu:
> >>>After perf_evlist__filter_pollfd() filters out fds and releases
> >>>perf_mmap by using perf_evlist__mmap_put(), refcnt of perf_mmap hits 1
> >>>then perf_evlist__mmap_consume() will do the final unmap. In this
> >>>condition, perf_evlist__mmap_read() will crash by referencing invalid
> >>>mmap. Put refcnt check before use.
> >>>
> >>>Can be reproduced as following:
> >>After applying 1/2 in this series and trying to reproduce I couldn't, it
> >>works, looking at the code...
> >>
> >>Let me get my head around this, idea was that after all fds associated
> >>with a mmap would be closed, i.e. the perf_mmap->refcnt hits zero, then
> >>we would have to drain whatever was left in the mmap, but looking again
> >>that doesn't look like that is what is doing, becaue in filter_pollfd we
> >>will munmap it before being able to "drain" it, as all mmaps were
> >>closed, thus filter_pollfd returned zero...
> >
> >In function __perf_evlist__mmap(), refcnt is initialized to 2, see commit:
> >  823969860329 ("perf evlist: Refcount mmaps")
> >
> >After filter_pollfd,  perf_mmap->refcnt is 1 not 0.
> >
> >  perf_evlist__filter_pollfd()                     -- refcnt=1
> >  draining = true
> >  if (perf_evlist__mmap_read() != NULL)
> >          perf_evlist__mmap_consume()    -- unmap, refcnt = 0
> >          perf_evlist__mmap_read()            -- segfault
> >else
> >exit
> >
> >I noticed that this issue also exists in builtin-record.c, but it
> >checks before mmap_read():
> >
> >if (rec->evlist->mmap[i].base) {
> >        if (record__mmap_read(rec, i, draining) != 0) {
> >
> >So we can either do the check outside
> >builtin-trace.c:perf_evlist__mmap_read() like what
> >builtin-record.c do or inside. What's your opinion?
> 
> I found the issue is still there, so ping...

Right, I noticed it as well sometimes, will apply the bandaid and leave
properly researching it for later.

- Arnaldo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] perf trace: Fix segmentfault on perf trace
  2015-05-11 13:47         ` Arnaldo Carvalho de Melo
@ 2015-05-11 13:57           ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-05-11 13:57 UTC (permalink / raw)
  To: He Kuang; +Cc: a.p.zijlstra, mingo, jolsa, wangnan0, linux-kernel

Em Mon, May 11, 2015 at 10:47:34AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, May 11, 2015 at 08:11:14PM +0800, He Kuang escreveu:
> > >So we can either do the check outside
> > >builtin-trace.c:perf_evlist__mmap_read() like what
> > >builtin-record.c do or inside. What's your opinion?
> > 
> > I found the issue is still there, so ping...
> 
> Right, I noticed it as well sometimes, will apply the bandaid and leave
> properly researching it for later.

Trying to research it now...

- Arnaldo

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-05-11 13:57 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-07  9:31 [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty He Kuang
2015-04-07  9:31 ` [PATCH 2/2] perf trace: Fix segmentfault on perf trace He Kuang
2015-04-07 12:36   ` Arnaldo Carvalho de Melo
2015-04-08  3:15     ` He Kuang
2015-05-11 12:11       ` He Kuang
2015-05-11 13:47         ` Arnaldo Carvalho de Melo
2015-05-11 13:57           ` Arnaldo Carvalho de Melo
2015-04-07 11:59 ` [PATCH 1/2] perf evlist: Fix inverted logic in perf_mmap__empty Arnaldo Carvalho de Melo
2015-04-08 15:10 ` [tip:perf/core] " tip-bot for He Kuang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.