Message ID | 20231219075320.165227-7-ray.huang@amd.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Support blob memory and venus on qemu | expand |
On 2023/12/19 16:53, Huang Rui wrote: > From: Xenia Ragiadakou <xenia.ragiadakou@amd.com> > > When the memory region has a different life-cycle from that of her parent, > could be automatically released, once has been unparent and once all of her > references have gone away, via the object's free callback. > > However, currently, the address space subsystem keeps references to the > memory region without first incrementing its object's reference count. > As a result, the automatic deallocation of the object, not taking into > account those references, results in use-after-free memory corruption. > > More specifically, reference to the memory region is kept in flatview > ranges. If the reference count of the memory region is not incremented, > flatview_destroy(), that is asynchronous, may be called after memory > region's destruction. If the reference count of the memory region is > incremented, memory region's destruction will take place after > flatview_destroy() has released its references. > > This patch increases the reference count of an owned memory region object > on each memory_region_ref() and decreases it on each memory_region_unref(). Why not pass the memory region itself as the owner parameter of memory_region_init_ram_ptr()?
On 21/12/23 07:45, Akihiko Odaki wrote: > On 2023/12/19 16:53, Huang Rui wrote: >> From: Xenia Ragiadakou <xenia.ragiadakou@amd.com> >> >> When the memory region has a different life-cycle from that of her >> parent, >> could be automatically released, once has been unparent and once all >> of her >> references have gone away, via the object's free callback. >> >> However, currently, the address space subsystem keeps references to the >> memory region without first incrementing its object's reference count. >> As a result, the automatic deallocation of the object, not taking into >> account those references, results in use-after-free memory corruption. >> >> More specifically, reference to the memory region is kept in flatview >> ranges. If the reference count of the memory region is not incremented, >> flatview_destroy(), that is asynchronous, may be called after memory >> region's destruction. If the reference count of the memory region is >> incremented, memory region's destruction will take place after >> flatview_destroy() has released its references. >> >> This patch increases the reference count of an owned memory region object >> on each memory_region_ref() and decreases it on each >> memory_region_unref(). > > Why not pass the memory region itself as the owner parameter of > memory_region_init_ram_ptr()? Hmm, in that case, how will it be guaranteed that the VirtIOGPU won't disappear while the memory region is still in use?
On 2023/12/21 16:35, Xenia Ragiadakou wrote: > > On 21/12/23 07:45, Akihiko Odaki wrote: >> On 2023/12/19 16:53, Huang Rui wrote: >>> From: Xenia Ragiadakou <xenia.ragiadakou@amd.com> >>> >>> When the memory region has a different life-cycle from that of her >>> parent, >>> could be automatically released, once has been unparent and once all >>> of her >>> references have gone away, via the object's free callback. >>> >>> However, currently, the address space subsystem keeps references to the >>> memory region without first incrementing its object's reference count. >>> As a result, the automatic deallocation of the object, not taking into >>> account those references, results in use-after-free memory corruption. >>> >>> More specifically, reference to the memory region is kept in flatview >>> ranges. If the reference count of the memory region is not incremented, >>> flatview_destroy(), that is asynchronous, may be called after memory >>> region's destruction. If the reference count of the memory region is >>> incremented, memory region's destruction will take place after >>> flatview_destroy() has released its references. >>> >>> This patch increases the reference count of an owned memory region >>> object >>> on each memory_region_ref() and decreases it on each >>> memory_region_unref(). >> >> Why not pass the memory region itself as the owner parameter of >> memory_region_init_ram_ptr()? > > Hmm, in that case, how will it be guaranteed that the VirtIOGPU won't > disappear while the memory region is still in use? You can object_ref() when you do memory_region_init_ram_ptr() and object_unref() when the memory region is being destroyed.
On 21/12/23 09:50, Akihiko Odaki wrote: > On 2023/12/21 16:35, Xenia Ragiadakou wrote: >> >> On 21/12/23 07:45, Akihiko Odaki wrote: >>> On 2023/12/19 16:53, Huang Rui wrote: >>>> From: Xenia Ragiadakou <xenia.ragiadakou@amd.com> >>>> >>>> When the memory region has a different life-cycle from that of her >>>> parent, >>>> could be automatically released, once has been unparent and once all >>>> of her >>>> references have gone away, via the object's free callback. >>>> >>>> However, currently, the address space subsystem keeps references to the >>>> memory region without first incrementing its object's reference count. >>>> As a result, the automatic deallocation of the object, not taking into >>>> account those references, results in use-after-free memory corruption. >>>> >>>> More specifically, reference to the memory region is kept in flatview >>>> ranges. If the reference count of the memory region is not incremented, >>>> flatview_destroy(), that is asynchronous, may be called after memory >>>> region's destruction. If the reference count of the memory region is >>>> incremented, memory region's destruction will take place after >>>> flatview_destroy() has released its references. >>>> >>>> This patch increases the reference count of an owned memory region >>>> object >>>> on each memory_region_ref() and decreases it on each >>>> memory_region_unref(). >>> >>> Why not pass the memory region itself as the owner parameter of >>> memory_region_init_ram_ptr()? >> >> Hmm, in that case, how will it be guaranteed that the VirtIOGPU won't >> disappear while the memory region is still in use? > > You can object_ref() when you do memory_region_init_ram_ptr() and > object_unref() when the memory region is being destroyed. It is not very intuitive but I see your point. This change is quite intrusive and has little use. I think it can be worked around in the way you suggest.
diff --git a/system/memory.c b/system/memory.c index 304fa843ea..4d5e7e7a4c 100644 --- a/system/memory.c +++ b/system/memory.c @@ -1824,6 +1824,7 @@ void memory_region_ref(MemoryRegion *mr) * we do not ref/unref them because it slows down DMA sensibly. */ if (mr && mr->owner) { + object_ref(OBJECT(mr)); object_ref(mr->owner); } } @@ -1832,6 +1833,7 @@ void memory_region_unref(MemoryRegion *mr) { if (mr && mr->owner) { object_unref(mr->owner); + object_unref(OBJECT(mr)); } }