qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq
@ 2020-07-27 13:02 Keqian Zhu
  2020-07-27 14:37 ` Li Qiang
  2020-07-27 14:41 ` Peter Maydell
  0 siblings, 2 replies; 8+ messages in thread
From: Keqian Zhu @ 2020-07-27 13:02 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: Thomas Huth, yezengruan, Keqian Zhu, Li Qiang,
	Dr . David Alan Gilbert, Esteban Bosse, Paolo Bonzini,
	wanghaibin.wang, Philippe Mathieu-Daudé

Avoid covering object refcount of qemu_irq, otherwise it may causes
memory leak.

Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
---
 hw/core/irq.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/core/irq.c b/hw/core/irq.c
index fb3045b912..59af4dfc74 100644
--- a/hw/core/irq.c
+++ b/hw/core/irq.c
@@ -125,7 +125,9 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
     int i;
     qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
     for (i = 0; i < n; i++) {
-        *old_irqs[i] = *gpio_in[i];
+        old_irqs[i]->handler = gpio_in[i]->handler;
+        old_irqs[i]->opaque = gpio_in[i]->opaque;
+
         gpio_in[i]->handler = handler;
         gpio_in[i]->opaque = &old_irqs[i];
     }
-- 
2.19.1



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

* Re: [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq
  2020-07-27 13:02 [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq Keqian Zhu
@ 2020-07-27 14:37 ` Li Qiang
  2020-07-28  1:29   ` zhukeqian
  2020-07-27 14:41 ` Peter Maydell
  1 sibling, 1 reply; 8+ messages in thread
From: Li Qiang @ 2020-07-27 14:37 UTC (permalink / raw)
  To: Keqian Zhu
  Cc: Thomas Huth, Esteban Bosse, Qemu Developers,
	Dr . David Alan Gilbert, yezengruan, qemu-arm, Paolo Bonzini,
	wanghaibin.wang, Philippe Mathieu-Daudé

Keqian Zhu <zhukeqian1@huawei.com> 于2020年7月27日周一 下午9:03写道:
>
> Avoid covering object refcount of qemu_irq, otherwise it may causes
> memory leak.

Any reproducer?

Thanks,
Li Qiang

>
> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
> ---
>  hw/core/irq.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/hw/core/irq.c b/hw/core/irq.c
> index fb3045b912..59af4dfc74 100644
> --- a/hw/core/irq.c
> +++ b/hw/core/irq.c
> @@ -125,7 +125,9 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
>      int i;
>      qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
>      for (i = 0; i < n; i++) {
> -        *old_irqs[i] = *gpio_in[i];
> +        old_irqs[i]->handler = gpio_in[i]->handler;
> +        old_irqs[i]->opaque = gpio_in[i]->opaque;
> +
>          gpio_in[i]->handler = handler;
>          gpio_in[i]->opaque = &old_irqs[i];
>      }
> --
> 2.19.1
>


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

* Re: [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq
  2020-07-27 13:02 [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq Keqian Zhu
  2020-07-27 14:37 ` Li Qiang
@ 2020-07-27 14:41 ` Peter Maydell
  2020-07-28  1:36   ` zhukeqian
  2020-07-28  8:48   ` Thomas Huth
  1 sibling, 2 replies; 8+ messages in thread
From: Peter Maydell @ 2020-07-27 14:41 UTC (permalink / raw)
  To: Keqian Zhu
  Cc: Thomas Huth, Esteban Bosse, Li Qiang, QEMU Developers,
	Dr . David Alan Gilbert, yezengruan, qemu-arm, wanghaibin.wang,
	Paolo Bonzini, Philippe Mathieu-Daudé

On Mon, 27 Jul 2020 at 14:03, Keqian Zhu <zhukeqian1@huawei.com> wrote:
>
> Avoid covering object refcount of qemu_irq, otherwise it may causes
> memory leak.
>
> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
> ---
>  hw/core/irq.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/hw/core/irq.c b/hw/core/irq.c
> index fb3045b912..59af4dfc74 100644
> --- a/hw/core/irq.c
> +++ b/hw/core/irq.c
> @@ -125,7 +125,9 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
>      int i;
>      qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
>      for (i = 0; i < n; i++) {
> -        *old_irqs[i] = *gpio_in[i];
> +        old_irqs[i]->handler = gpio_in[i]->handler;
> +        old_irqs[i]->opaque = gpio_in[i]->opaque;
> +
>          gpio_in[i]->handler = handler;
>          gpio_in[i]->opaque = &old_irqs[i];
>      }

This function is leaky by design, because it doesn't do anything
with the old_irqs array and there's no function for un-intercepting
the IRQs (which would need to free that memory). This is not ideal
but OK because it's only used in the test suite.

Is there a specific bug you're trying to fix here?

thanks
-- PMM


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

* Re: [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq
  2020-07-27 14:37 ` Li Qiang
@ 2020-07-28  1:29   ` zhukeqian
  0 siblings, 0 replies; 8+ messages in thread
From: zhukeqian @ 2020-07-28  1:29 UTC (permalink / raw)
  To: Li Qiang
  Cc: Thomas Huth, Esteban Bosse, Qemu Developers,
	Dr . David Alan Gilbert, yezengruan, qemu-arm, Paolo Bonzini,
	wanghaibin.wang, Philippe Mathieu-Daudé

Hi Qiang,

On 2020/7/27 22:37, Li Qiang wrote:
> Keqian Zhu <zhukeqian1@huawei.com> 于2020年7月27日周一 下午9:03写道:
>>
>> Avoid covering object refcount of qemu_irq, otherwise it may causes
>> memory leak.
> 
> Any reproducer?
> 
In mainline Qemu. this function is only used in qtest. One of our internal
self-developed module also use this function. The memory leak is reported
by ASAN.

Thanks,
Keqian

> Thanks,
> Li Qiang
> 
>>
>> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
>> ---
>>  hw/core/irq.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/core/irq.c b/hw/core/irq.c
>> index fb3045b912..59af4dfc74 100644
>> --- a/hw/core/irq.c
>> +++ b/hw/core/irq.c
>> @@ -125,7 +125,9 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
>>      int i;
>>      qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
>>      for (i = 0; i < n; i++) {
>> -        *old_irqs[i] = *gpio_in[i];
>> +        old_irqs[i]->handler = gpio_in[i]->handler;
>> +        old_irqs[i]->opaque = gpio_in[i]->opaque;
>> +
>>          gpio_in[i]->handler = handler;
>>          gpio_in[i]->opaque = &old_irqs[i];
>>      }
>> --
>> 2.19.1
>>
> .
> 


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

* Re: [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq
  2020-07-27 14:41 ` Peter Maydell
@ 2020-07-28  1:36   ` zhukeqian
  2020-07-28  8:48   ` Thomas Huth
  1 sibling, 0 replies; 8+ messages in thread
From: zhukeqian @ 2020-07-28  1:36 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Thomas Huth, Esteban Bosse, Li Qiang, QEMU Developers,
	Dr . David Alan Gilbert, yezengruan, qemu-arm, wanghaibin.wang,
	Paolo Bonzini, Philippe Mathieu-Daudé

Hi Peter,

On 2020/7/27 22:41, Peter Maydell wrote:
> On Mon, 27 Jul 2020 at 14:03, Keqian Zhu <zhukeqian1@huawei.com> wrote:
>>
>> Avoid covering object refcount of qemu_irq, otherwise it may causes
>> memory leak.
>>
>> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
>> ---
>>  hw/core/irq.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/core/irq.c b/hw/core/irq.c
>> index fb3045b912..59af4dfc74 100644
>> --- a/hw/core/irq.c
>> +++ b/hw/core/irq.c
>> @@ -125,7 +125,9 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
>>      int i;
>>      qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
>>      for (i = 0; i < n; i++) {
>> -        *old_irqs[i] = *gpio_in[i];
>> +        old_irqs[i]->handler = gpio_in[i]->handler;
>> +        old_irqs[i]->opaque = gpio_in[i]->opaque;
>> +
>>          gpio_in[i]->handler = handler;
>>          gpio_in[i]->opaque = &old_irqs[i];
>>      }
> 
> This function is leaky by design, because it doesn't do anything
> with the old_irqs array and there's no function for un-intercepting
> the IRQs (which would need to free that memory). This is not ideal
> but OK because it's only used in the test suite.
One of our internal self-developed module also use this function, and we
implemented a function to remove intercepting, so there is no memory leak
after this bugfix.

I suggest to merge this bugfix to prepare for future code which may invoke
this function.

> 
> Is there a specific bug you're trying to fix here?
The memory leak is reported by ASAN.
> 

Thanks,
Keqian
> thanks
> -- PMM
> .
> 


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

* Re: [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq
  2020-07-27 14:41 ` Peter Maydell
  2020-07-28  1:36   ` zhukeqian
@ 2020-07-28  8:48   ` Thomas Huth
  2020-07-28  9:05     ` zhukeqian
  2020-07-28  9:48     ` Peter Maydell
  1 sibling, 2 replies; 8+ messages in thread
From: Thomas Huth @ 2020-07-28  8:48 UTC (permalink / raw)
  To: Peter Maydell, Keqian Zhu
  Cc: yezengruan, Li Qiang, QEMU Developers, Dr . David Alan Gilbert,
	Esteban Bosse, qemu-arm, wanghaibin.wang, Paolo Bonzini,
	Philippe Mathieu-Daudé

On 27/07/2020 16.41, Peter Maydell wrote:
> On Mon, 27 Jul 2020 at 14:03, Keqian Zhu <zhukeqian1@huawei.com> wrote:
>>
>> Avoid covering object refcount of qemu_irq, otherwise it may causes
>> memory leak.
>>
>> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
>> ---
>>  hw/core/irq.c | 4 +++-
>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/core/irq.c b/hw/core/irq.c
>> index fb3045b912..59af4dfc74 100644
>> --- a/hw/core/irq.c
>> +++ b/hw/core/irq.c
>> @@ -125,7 +125,9 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
>>      int i;
>>      qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
>>      for (i = 0; i < n; i++) {
>> -        *old_irqs[i] = *gpio_in[i];
>> +        old_irqs[i]->handler = gpio_in[i]->handler;
>> +        old_irqs[i]->opaque = gpio_in[i]->opaque;
>> +
>>          gpio_in[i]->handler = handler;
>>          gpio_in[i]->opaque = &old_irqs[i];
>>      }
> 
> This function is leaky by design, because it doesn't do anything
> with the old_irqs array and there's no function for un-intercepting
> the IRQs (which would need to free that memory). This is not ideal
> but OK because it's only used in the test suite.

I think this could better be done without calling qemu_allocate_irqs():
Simply call qemu_allocate_irq() (without "s" at the end) within the
for-loop for each irq instead. What do you think?

 Thomas



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

* Re: [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq
  2020-07-28  8:48   ` Thomas Huth
@ 2020-07-28  9:05     ` zhukeqian
  2020-07-28  9:48     ` Peter Maydell
  1 sibling, 0 replies; 8+ messages in thread
From: zhukeqian @ 2020-07-28  9:05 UTC (permalink / raw)
  To: Thomas Huth, Peter Maydell
  Cc: Esteban Bosse, Li Qiang, QEMU Developers, Dr . David Alan Gilbert,
	yezengruan, qemu-arm, Paolo Bonzini, wanghaibin.wang,
	Philippe Mathieu-Daudé

Hi Thomas,

On 2020/7/28 16:48, Thomas Huth wrote:
> On 27/07/2020 16.41, Peter Maydell wrote:
>> On Mon, 27 Jul 2020 at 14:03, Keqian Zhu <zhukeqian1@huawei.com> wrote:
>>>
>>> Avoid covering object refcount of qemu_irq, otherwise it may causes
>>> memory leak.
>>>
>>> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
>>> ---
>>>  hw/core/irq.c | 4 +++-
>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/hw/core/irq.c b/hw/core/irq.c
>>> index fb3045b912..59af4dfc74 100644
>>> --- a/hw/core/irq.c
>>> +++ b/hw/core/irq.c
>>> @@ -125,7 +125,9 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
>>>      int i;
>>>      qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
>>>      for (i = 0; i < n; i++) {
>>> -        *old_irqs[i] = *gpio_in[i];
>>> +        old_irqs[i]->handler = gpio_in[i]->handler;
>>> +        old_irqs[i]->opaque = gpio_in[i]->opaque;
>>> +
>>>          gpio_in[i]->handler = handler;
>>>          gpio_in[i]->opaque = &old_irqs[i];
>>>      }
>>
>> This function is leaky by design, because it doesn't do anything
>> with the old_irqs array and there's no function for un-intercepting
>> the IRQs (which would need to free that memory). This is not ideal
>> but OK because it's only used in the test suite.
> 
> I think this could better be done without calling qemu_allocate_irqs():
> Simply call qemu_allocate_irq() (without "s" at the end) within the
> for-loop for each irq instead. What do you think?
Yeah, this can save some memory. But I think it does not solve the refcount covering
problem.
> 
Thanks
Keqian
>  Thomas
> 
> 
> 


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

* Re: [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq
  2020-07-28  8:48   ` Thomas Huth
  2020-07-28  9:05     ` zhukeqian
@ 2020-07-28  9:48     ` Peter Maydell
  1 sibling, 0 replies; 8+ messages in thread
From: Peter Maydell @ 2020-07-28  9:48 UTC (permalink / raw)
  To: Thomas Huth
  Cc: Esteban Bosse, Philippe Mathieu-Daudé, Li Qiang,
	QEMU Developers, Dr . David Alan Gilbert, yezengruan, qemu-arm,
	wanghaibin.wang, Paolo Bonzini, Keqian Zhu

On Tue, 28 Jul 2020 at 09:48, Thomas Huth <thuth@redhat.com> wrote:
>
> On 27/07/2020 16.41, Peter Maydell wrote:
> > On Mon, 27 Jul 2020 at 14:03, Keqian Zhu <zhukeqian1@huawei.com> wrote:
> >>
> >> Avoid covering object refcount of qemu_irq, otherwise it may causes
> >> memory leak.
> >>
> >> Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
> >> ---
> >>  hw/core/irq.c | 4 +++-
> >>  1 file changed, 3 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/hw/core/irq.c b/hw/core/irq.c
> >> index fb3045b912..59af4dfc74 100644
> >> --- a/hw/core/irq.c
> >> +++ b/hw/core/irq.c
> >> @@ -125,7 +125,9 @@ void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
> >>      int i;
> >>      qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n);
> >>      for (i = 0; i < n; i++) {
> >> -        *old_irqs[i] = *gpio_in[i];
> >> +        old_irqs[i]->handler = gpio_in[i]->handler;
> >> +        old_irqs[i]->opaque = gpio_in[i]->opaque;
> >> +
> >>          gpio_in[i]->handler = handler;
> >>          gpio_in[i]->opaque = &old_irqs[i];
> >>      }
> >
> > This function is leaky by design, because it doesn't do anything
> > with the old_irqs array and there's no function for un-intercepting
> > the IRQs (which would need to free that memory). This is not ideal
> > but OK because it's only used in the test suite.
>
> I think this could better be done without calling qemu_allocate_irqs():
> Simply call qemu_allocate_irq() (without "s" at the end) within the
> for-loop for each irq instead. What do you think?

Well, what are we trying to do with the function? I think that
your suggestion still doesn't really fix the leak in the sense
that there's no mechanism for undoing the operation and freeing
the memory allocated by qemu_allocate_irq(). The whole concept
of the function is pretty dubious because it's arbitrarily
re-plugging IRQs, which in the whole of the rest of QEMU are
assumed to be something that's wired up by board code or by
an SoC device that "owns" the two devices it's connecting.
That's fine for test-case purposes, and for the qtest code that
is the only in-tree user of this function we could construct a
(nominally) leak-free version of the function by having it return
some kind of handle that could be passed to a
qemu_irq_remove_intercept_in() to clean up [this would fix a
Coverity nag, which would be the main benefit...].

I agree that copying the refcount here looks wrong, but in
what situation is the refcount on any of the qemu_irqs
involved changing anyway?

For non-testing uses of this function it gets trickier (what if the
device on one end or the other is destroyed while the intercept is
in place, for instance?) So I'm a bit sceptical of ideas about
extending the uses of this function to non-test-code, and I think
I'd want to see what the intended non-test uses were...

thanks
-- PMM


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

end of thread, other threads:[~2020-07-28  9:49 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-07-27 13:02 [PATCH] bugfix: irq: Avoid covering object refcount of qemu_irq Keqian Zhu
2020-07-27 14:37 ` Li Qiang
2020-07-28  1:29   ` zhukeqian
2020-07-27 14:41 ` Peter Maydell
2020-07-28  1:36   ` zhukeqian
2020-07-28  8:48   ` Thomas Huth
2020-07-28  9:05     ` zhukeqian
2020-07-28  9:48     ` Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).