[PATCH] wayland-util: fix wrap-back of wl_map->free_list when client id >= 0x80000000
Chang Liu
cl91tp at gmail.com
Sun Sep 8 04:11:28 PDT 2013
The current implementation of wl_map uses uint32_t for free_list.
When removing client id >= 0x80000000, shifting said id by 1 bit left
will cause free_list to wrap back to 0x0. Bump both wl_map->free_list
and union_entry->next to uint64_t to fix this problem.
---
The relavent lines are:
In wl_map_remove:
start[i].next = map->free_list;
map->free_list = (i << 1) | 1;
If we are removing a client id i >= 0x80000000, the MSB of i will be lost
when we perform i << 1, and this causes free_list to wrap back to 0x0.
In wl_map_insert_new:
if (map->free_list) {
entry = &start[map->free_list >> 1];
map->free_list = entry->next;
}
With free_list wrapped back to 0x0, we are longer able to recover the missing
MSB in the client id even if we perform a right-shift to free_list.
src/wayland-private.h | 2 +-
src/wayland-util.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/wayland-private.h b/src/wayland-private.h
index 67e8783..5b3715d 100644
--- a/src/wayland-private.h
+++ b/src/wayland-private.h
@@ -63,7 +63,7 @@ struct wl_map {
struct wl_array client_entries;
struct wl_array server_entries;
uint32_t side;
- uint32_t free_list;
+ uint64_t free_list;
};
typedef void (*wl_iterator_func_t)(void *element, void *data);
diff --git a/src/wayland-util.c b/src/wayland-util.c
index 4fe9c81..1798fd6 100644
--- a/src/wayland-util.c
+++ b/src/wayland-util.c
@@ -149,12 +149,12 @@ wl_array_copy(struct wl_array *array, struct wl_array *source)
}
union map_entry {
- uintptr_t next;
+ uint64_t next;
void *data;
};
#define map_entry_is_free(entry) ((entry).next & 0x1)
-#define map_entry_get_data(entry) ((void *)((entry).next & ~(uintptr_t)0x3))
+#define map_entry_get_data(entry) ((void *)((entry).next & ~0x3))
#define map_entry_get_flags(entry) (((entry).next >> 1) & 0x1)
WL_EXPORT void
@@ -291,7 +291,7 @@ wl_map_remove(struct wl_map *map, uint32_t i)
start = entries->data;
start[i].next = map->free_list;
- map->free_list = (i << 1) | 1;
+ map->free_list = ((uint64_t)i << 1) | 1;
}
WL_EXPORT void *
--
1.8.3.4
More information about the wayland-devel
mailing list