All of lore.kernel.org
 help / color / mirror / Atom feed
From: Don Slutz <don.slutz@gmail.com>
To: Paolo Bonzini <pbonzini@redhat.com>,
	"Gonglei (Arei)" <arei.gonglei@huawei.com>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Cc: Peter Crosthwaite <crosthwaite.peter@gmail.com>,
	Richard Henderson <rth@twiddle.net>
Subject: Re: [Qemu-devel] [PATCH] exec: Stop using memory after free
Date: Wed, 2 Dec 2015 17:01:41 -0500	[thread overview]
Message-ID: <565F6A45.2080900@Gmail.com> (raw)
In-Reply-To: <565EBE31.7010304@redhat.com>

On 12/02/15 04:47, Paolo Bonzini wrote:
> 
> 
> On 02/12/2015 08:59, Gonglei (Arei) wrote:
>>>>>  static void phys_section_destroy(MemoryRegion *mr)  {
>>>>> +    bool have_sub_page = mr->subpage;
>>>>> +
>>>>>      memory_region_unref(mr);
>>>>>
>>>>> -    if (mr->subpage) {
>>>>> +    if (have_sub_page) {
>>>>>          subpage_t *subpage = container_of(mr, subpage_t, iomem);
>>
>> Can we use the *mr* here again?
> 
> Yes, in the subpage case the memory is allocated by exec.c.  Accessing
> mr->subpage is only problematic if memory_region_unref destroys a device.
> 

My memory of debugging this in June, was that when ever subpage is true
the reference count on the mr was greater then (>2?) so that after the
call on memory_region_unref(mr), the reference count on the mr was still
non-zero and so g_free() was not called.

>> IMO we should invoke memory_region_unref(mr) after the if check.
> 
> That's also possible.

My attempts to do so all failed, maybe coding bugs.  At that time I came
up with the patch:

commit 475d53a44933171222516689ae00e7fad5a8bf69
Author: Don Slutz <dslutz@verizon.com>
Date:   Sat Jun 6 10:13:08 2015 -0400

    exec: Do not use MemoryRegion after free

    Here is gdb output that shows this happening:

      Breakpoint 3, object_finalize (data=0x7fdf32a14010) at
qom/object.c:417
      417             obj->free(obj);
      (gdb) bt
      #0  object_finalize (data=0x7fdf32a14010) at qom/object.c:417
      #1  0x00000000007329d4 in object_unref (obj=0x7fdf32a14010) at
qom/object.c:720
      #2  0x0000000000468a65 in memory_region_unref (mr=0x7fdf32a168b0)
at /home/don/xen/tools/qemu-xen-dir/memory.c:1359
      #3  0x000000000040eb52 in phys_section_destroy (mr=0x7fdf32a168b0)
at /home/don/xen/tools/qemu-xen-dir/exec.c:960
      #4  0x000000000040ec0a in phys_sections_free (map=0x3e51fc8) at
/home/don/xen/tools/qemu-xen-dir/exec.c:973
      #5  0x0000000000411cc9 in address_space_dispatch_free
(d=0x3e51fb0) at /home/don/xen/tools/qemu-xen-dir/exec.c:2133
      #6  0x0000000000840ae2 in call_rcu_thread (opaque=0x0) at
util/rcu.c:256
      #7  0x00000032fdc07d14 in start_thread (arg=0x7fdf34866700) at
pthread_create.c:309
      #8  0x00000032fd4f168d in clone () at
../sysdeps/unix/sysv/linux/x86_64/clone.S:115
      (gdb) p obj
      $5 = (Object *) 0x7fdf32a14010
      (gdb) p *obj
      $6 = {class = 0x302f380, free = 0x40a1e0 <g_free@plt>, properties
= {tqh_first = 0x0, tqh_last = 0x7fdf32a14020},
      ref = 0, parent = 0x0}
      (gdb) up
      #1  0x00000000007329d4 in object_unref (obj=0x7fdf32a14010) at
qom/object.c:720
      720             object_finalize(obj);
      (gdb) up
      #2  0x0000000000468a65 in memory_region_unref (mr=0x7fdf32a168b0)
at /home/don/xen/tools/qemu-xen-dir/memory.c:1359
      1359            object_unref(obj->parent);
      (gdb) up
      #3  0x000000000040eb52 in phys_section_destroy (mr=0x7fdf32a168b0)
at /home/don/xen/tools/qemu-xen-dir/exec.c:960
      960         memory_region_unref(mr);
      (gdb) l
      955         return map->sections_nb++;
      956     }
      957
      958     static void phys_section_destroy(MemoryRegion *mr)
      959     {
      960         memory_region_unref(mr);
      961
      962         if (mr->subpage) {
      963             subpage_t *subpage = container_of(mr, subpage_t,
iomem);
      964             object_unref(OBJECT(&subpage->iomem));
      (gdb) p mr
      $7 = (MemoryRegion *) 0x7fdf32a168b0
      (gdb) p mr->subpage
      $9 = false
      (gdb) n
      419     }
      (gdb) n
      object_unref (obj=0x7fdf32a14010) at qom/object.c:722
      722     }
      (gdb) n
      memory_region_unref (mr=0x7fdf32a168b0) at
/home/don/xen/tools/qemu-xen-dir/memory.c:1363
      1363    }
      (gdb) n
      phys_section_destroy (mr=0x7fdf32a168b0) at
/home/don/xen/tools/qemu-xen-dir/exec.c:962
      962         if (mr->subpage) {
      (gdb) p mr
      $10 = (MemoryRegion *) 0x7fdf32a168b0
      (gdb) p *mr
      Cannot access memory at address 0x7fdf32a168b0

    Signed-off-by: Don Slutz <dslutz@verizon.com>

diff --git a/exec.c b/exec.c
index f7883d2..b4be5d9 100644
--- a/exec.c
+++ b/exec.c
@@ -958,10 +958,14 @@ static uint16_t phys_section_add(PhysPageMap *map,

 static void phys_section_destroy(MemoryRegion *mr)
 {
-    memory_region_unref(mr);
+    subpage_t *subpage = NULL;

     if (mr->subpage) {
-        subpage_t *subpage = container_of(mr, subpage_t, iomem);
+        subpage = container_of(mr, subpage_t, iomem);
+    }
+    memory_region_unref(mr);
+
+    if (subpage) {
         object_unref(OBJECT(&subpage->iomem));
         g_free(subpage);
     }

which never got posted do to external events.  When I hit this again, I
was able to remember enough to generate this patch from scratch.  I only
found this patch when reading this email thread.

   -Don Slutz
P.S. I no longer work for verizon, and so the email address above no
longer works.


> 
> Paolo
> 

  reply	other threads:[~2015-12-02 22:01 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-30 22:11 [Qemu-devel] [PATCH] exec: Stop using memory after free Don Slutz
2015-12-01  9:52 ` Paolo Bonzini
2015-12-01 13:05   ` Gonglei (Arei)
2015-12-02  7:59   ` Gonglei (Arei)
2015-12-02  9:47     ` Paolo Bonzini
2015-12-02 22:01       ` Don Slutz [this message]
2015-12-02 22:04   ` Don Slutz

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=565F6A45.2080900@Gmail.com \
    --to=don.slutz@gmail.com \
    --cc=arei.gonglei@huawei.com \
    --cc=crosthwaite.peter@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /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.