mirror of
https://github.com/mii443/qemu.git
synced 2025-12-12 05:18:37 +00:00
memory: avoid "resurrection" of dead FlatViews
It's possible for address_space_get_flatview() as it currently stands
to cause a use-after-free for the returned FlatView, if the reference
count is incremented after the FlatView has been replaced by a writer:
thread 1 thread 2 RCU thread
-------------------------------------------------------------
rcu_read_lock
read as->current_map
set as->current_map
flatview_unref
'--> call_rcu
flatview_ref
[ref=1]
rcu_read_unlock
flatview_destroy
<badness>
Since FlatViews are not updated very often, we can just detect the
situation using a new atomic op atomic_fetch_inc_nonzero, similar to
Linux's atomic_inc_not_zero, which performs the refcount increment only if
it hasn't already hit zero. This is similar to Linux commit de09a9771a53
("CRED: Fix get_task_cred() and task_state() to not resurrect dead
credentials", 2010-07-29).
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
@@ -442,4 +442,12 @@
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#define atomic_fetch_inc_nonzero(ptr) ({ \
|
||||
typeof_strip_qual(*ptr) _oldn = atomic_read(ptr); \
|
||||
while (_oldn && atomic_cmpxchg(ptr, _oldn, _oldn + 1) != _oldn) { \
|
||||
_oldn = atomic_read(ptr); \
|
||||
} \
|
||||
_oldn; \
|
||||
})
|
||||
|
||||
#endif /* QEMU_ATOMIC_H */
|
||||
|
||||
Reference in New Issue
Block a user