On 2026/01/30 3:06, Paolo Bonzini wrote:
On 1/29/26 05:41, Akihiko Odaki wrote:
However, I see another problem in struct embedding; it breaks
object_ref(). When embedding, the child object effectively takes the
reference to the storage of the parent object, but this reference is
not counted, so use-after-free can happen if someone takes a reference
to the child object with object_ref(). That is why the wrapper of
object_ref() in rust/qom/src/qom.rs needs to be marked unsafe. Memory
regions workaround this with memory_region_ref(), but it's not perfect
since it relies on object_ref() in the end.
Yes, and in Rust the idea was to have (in addition to Owned<T> which is
for an allocated object) another smart pointer Child<'a, T>: an embedded
object that is owned (the parent has a reference and a field of type
Child releases that reference when the parent is finalized) but cannot
be cloned.
For this reason I think object_initialize(),
object_initialize_child(), and the like are better to be noted as
deprecated in
include/qom/object.h. Then memory_region_init() can be deprecated
referring to them.
This would be huge and I don't think it's feasible.
It also only provides the appearance of safety. If you have a backwards
pointer (such as the memory region's owner), you still have either a
leak or the risk of a use-after-free.
Now I'm starting to recover my memory on the situation of this matter. I
have actually written patches to make struct embedding safe and also
deal with memory region's owner. My tree that include them can be found at:
https://gitlab.com/akihiko.odaki/qemu/-/tree/51066314fcff96303c1ad5814c3d74027855a7cb
Making struct embedding safe is done by introducing another reference
counter for storage. So the reference graph will be looked like the
following:
Owner -+-> Owner's storage
MR ----+
Memory region's backward references to their owning devices are
invalidated when unrealizing the devices. The reasoning here is that the
corner cases where devices are accessed after unrealization are unlikely
to be handled properly, so they are better to be forbidden.
Users other than memory regions may still have backward pointers that
are not properly tracked, so the Rust wrapper of object_ref() is still
marked unsafe.
Regards,
Akihiko Odaki