All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: "Philippe Mathieu-Daudé" <philmd@redhat.com>
Cc: zhanghailiang <zhang.zhanghailiang@huawei.com>,
	Alistair Francis <alistair@alistair23.me>,
	Pan Nengyuan <pannengyuan@huawei.com>,
	QEMU Developers <qemu-devel@nongnu.org>,
	mav2-rk.cave-ayland@ilande.co.uk, qemu-arm <qemu-arm@nongnu.org>,
	qemu-ppc <qemu-ppc@nongnu.org>,
	Euler Robot <euler.robot@huawei.com>,
	"Edgar E. Iglesias" <edgar.iglesias@gmail.com>,
	David Gibson <david@gibson.dropbear.id.au>
Subject: Re: [PATCH v2 2/2] hw: move timer_new from init() into realize() to avoid memleaks
Date: Thu, 20 Feb 2020 21:20:55 +0000	[thread overview]
Message-ID: <CAFEAcA8ovMyTGNB_NA8ybPLdnneKjvNFY=qyP0DEFS9cmUJo-g@mail.gmail.com> (raw)
In-Reply-To: <747a3358-09af-d4fa-9150-57ad3e349f24@redhat.com>

On Thu, 20 Feb 2020 at 18:52, Philippe Mathieu-Daudé <philmd@redhat.com> wrote:
>
> On 2/20/20 6:56 PM, Peter Maydell wrote:
> > On Mon, 17 Feb 2020 at 03:22, <pannengyuan@huawei.com> wrote:
> >>
> >> From: Pan Nengyuan <pannengyuan@huawei.com>
> >>
> >> There are some memleaks when we call 'device_list_properties'. This patch move timer_new from init into realize to fix it.
> >> Meanwhile, do the null check in mos6522_reset() to avoid null deref if we move timer_new into realize().
> >>
> >> Reported-by: Euler Robot <euler.robot@huawei.com>
> >> Signed-off-by: Pan Nengyuan <pannengyuan@huawei.com>
> >> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> >
> >
> >> diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
> >> index 19e154b870..980eda7599 100644
> >> --- a/hw/misc/mos6522.c
> >> +++ b/hw/misc/mos6522.c
> >> @@ -465,11 +465,15 @@ static void mos6522_reset(DeviceState *dev)
> >>       s->timers[0].frequency = s->frequency;
> >>       s->timers[0].latch = 0xffff;
> >>       set_counter(s, &s->timers[0], 0xffff);
> >> -    timer_del(s->timers[0].timer);
> >> +    if (s->timers[0].timer) {
> >> +        timer_del(s->timers[0].timer);
> >> +    }
> >>
> >>       s->timers[1].frequency = s->frequency;
> >>       s->timers[1].latch = 0xffff;
> >> -    timer_del(s->timers[1].timer);
> >> +    if (s->timers[1].timer) {
> >> +        timer_del(s->timers[1].timer);
> >> +    }
> >>   }
> >
> > What code path calls a device 'reset' method on a device
> > that has not yet been realized ? I wasn't expecting that
> > to be valid...
>
> This is not valid. What I understood while reviewing this patch is on
> reset the timer is removed from the timers list. But this patch miss
> setting timer = NULL in case the device is reset multiple times, here
> can happen a NULL deref.

I should have checked the APIs here.

timer_new() allocates memory and initialises a timer.
timer_del() removes a timer from any list it is on, but
does not deallocate memory. It's the function you call
to stop a timer (and arguably timer_stop() would be a
better name for it).
If you created the timer with timer_init(), then the
code to clean it up is:
 (1) call timer_del() to make sure it's not on any
list of active timers
 (2) call timer_free()

So:
 * the mos6522_reset code is fine as it is
 * if we wanted cleanup code that undoes the timer_new
   then that would be a timer_del() + timer_free().
   This would go in unrealize if the timer_new is put
   in realize, but...
 * ...like the other devices touched in this patch,
   mos6522 isn't user-creatable, so if realize succeeds
   it won't ever be destroyed; so we don't need to
   do that. (This is a little harder to check than
   with most of these devices, since mos6522 is an
   abstract base class for some other devices, but
   I think it's correct.)

Side notes:
 * for new code, rather than using timer_new() or one
   of its sibling functions, prefer timer_init(),
   timer_init_ns(), etc. These take a pointer to a
   pre-existing QEMUTimer, typically one you have
   directly embedded in the device state struct. So
   they don't need to be freed on unrealize (though
   you do still want to make sure the timer is not
   on an active list with timer_del() before the memory
   in the device state struct goes away).
 * maybe timer_free() should call timer_del(),
   rather than obliging the caller to?

thanks
-- PMM


  reply	other threads:[~2020-02-20 21:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-17  3:21 [PATCH v2 0/2] delay timer_new from init to realize to fix memleaks pannengyuan
2020-02-17  3:21 ` [PATCH v2 1/2] s390x: fix memleaks in cpu_finalize pannengyuan
2020-02-17  9:45   ` Philippe Mathieu-Daudé
2020-02-20 15:59   ` Cornelia Huck
2020-02-20 16:49     ` Peter Maydell
2020-02-17  3:21 ` [PATCH v2 2/2] hw: move timer_new from init() into realize() to avoid memleaks pannengyuan
2020-02-20 17:56   ` Peter Maydell
2020-02-20 18:51     ` Philippe Mathieu-Daudé
2020-02-20 21:20       ` Peter Maydell [this message]
2020-02-21  3:37     ` Pan Nengyuan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFEAcA8ovMyTGNB_NA8ybPLdnneKjvNFY=qyP0DEFS9cmUJo-g@mail.gmail.com' \
    --to=peter.maydell@linaro.org \
    --cc=alistair@alistair23.me \
    --cc=david@gibson.dropbear.id.au \
    --cc=edgar.iglesias@gmail.com \
    --cc=euler.robot@huawei.com \
    --cc=mav2-rk.cave-ayland@ilande.co.uk \
    --cc=pannengyuan@huawei.com \
    --cc=philmd@redhat.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=zhang.zhanghailiang@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.