mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-03-30 11:11:05 -04:00
util: fix use-after-free in for_each_helper
for_each_helper caches the entries->data pointer and array size before iterating. If a compositor calls wl_client_for_each_resource() and the provided callback triggers the creation of a new client object, the underlying wl_array may be reallocated via realloc(). When this happens, the cached start pointer becomes dangling. Subsequent iterations will read from the freed memory block, causing already-destroyed resources to be destroyed a second time (e.g., leading to a double-free crash in wl_list_remove()). Fix this by dynamically re-fetching entries->data and entries->size on every loop iteration, ensuring the iterator always accesses the valid live array. Signed-off-by: YaNing Lu <luyaning@uniontech.com>
This commit is contained in:
parent
44b26e34e5
commit
e647f6304d
1 changed files with 5 additions and 3 deletions
|
|
@ -424,10 +424,12 @@ for_each_helper(struct wl_array *entries, wl_iterator_func_t func, void *data)
|
|||
union map_entry entry, *start;
|
||||
size_t count;
|
||||
|
||||
start = (union map_entry *) entries->data;
|
||||
count = entries->size / sizeof(union map_entry);
|
||||
for (size_t idx = 0; ; idx++) {
|
||||
count = entries->size / sizeof(union map_entry);
|
||||
if (idx >= count)
|
||||
break;
|
||||
|
||||
for (size_t idx = 0; idx < count; idx++) {
|
||||
start = (union map_entry *) entries->data;
|
||||
entry = start[idx];
|
||||
if (entry.data && !map_entry_is_free(entry)) {
|
||||
ret = func(map_entry_get_data(entry), data, map_entry_get_flags(entry));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue