Add a "side" field and some sanity checks to wl_map.

The original wl_map implementation did no checking to ensures that ids fell
on the correct side of the WL_SERVER_ID_START line.  This meant that a
client could send the server a server ID and it would happily try to use
it.  Also, there was no distinction between server-side and client-side in
wl_map_remove.  Because wl_map_remove added the entry to the free list
regardless of which side it came from, the following set of actions would
break the map:

1. Client creates a bunch of objects
2. Client deletes one or more of those objects
3. Client does something that causes the server to create an object

Because of the problem in wl_map_remove, the server would take an old
client-side id, apply the WL_SERVER_ID_START offset, and try to use it as a
server-side id regardless of whether or not it was valid.

Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
Jason Ekstrand 2013-06-01 17:40:52 -05:00 committed by Kristian Høgsberg
parent dce104dcc2
commit 28472970df
4 changed files with 32 additions and 15 deletions

View file

@ -152,9 +152,10 @@ union map_entry {
};
WL_EXPORT void
wl_map_init(struct wl_map *map)
wl_map_init(struct wl_map *map, uint32_t side)
{
memset(map, 0, sizeof *map);
map->side = side;
}
WL_EXPORT void
@ -165,13 +166,13 @@ wl_map_release(struct wl_map *map)
}
WL_EXPORT uint32_t
wl_map_insert_new(struct wl_map *map, uint32_t side, void *data)
wl_map_insert_new(struct wl_map *map, void *data)
{
union map_entry *start, *entry;
struct wl_array *entries;
uint32_t base;
if (side == WL_MAP_CLIENT_SIDE) {
if (map->side == WL_MAP_CLIENT_SIDE) {
entries = &map->client_entries;
base = 0;
} else {
@ -203,8 +204,14 @@ wl_map_insert_at(struct wl_map *map, uint32_t i, void *data)
struct wl_array *entries;
if (i < WL_SERVER_ID_START) {
if (map->side == WL_MAP_CLIENT_SIDE)
return -1;
entries = &map->client_entries;
} else {
if (map->side == WL_MAP_SERVER_SIDE)
return -1;
entries = &map->server_entries;
i -= WL_SERVER_ID_START;
}
@ -230,8 +237,14 @@ wl_map_reserve_new(struct wl_map *map, uint32_t i)
struct wl_array *entries;
if (i < WL_SERVER_ID_START) {
if (map->side == WL_MAP_CLIENT_SIDE)
return -1;
entries = &map->client_entries;
} else {
if (map->side == WL_MAP_SERVER_SIDE)
return -1;
entries = &map->server_entries;
i -= WL_SERVER_ID_START;
}
@ -262,8 +275,14 @@ wl_map_remove(struct wl_map *map, uint32_t i)
struct wl_array *entries;
if (i < WL_SERVER_ID_START) {
if (map->side == WL_MAP_SERVER_SIDE)
return;
entries = &map->client_entries;
} else {
if (map->side == WL_MAP_CLIENT_SIDE)
return;
entries = &map->server_entries;
i -= WL_SERVER_ID_START;
}