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

@ -226,8 +226,7 @@ wl_proxy_create(struct wl_proxy *factory, const struct wl_interface *interface)
proxy->refcount = 1;
pthread_mutex_lock(&display->mutex);
proxy->object.id = wl_map_insert_new(&display->objects,
WL_MAP_CLIENT_SIDE, proxy);
proxy->object.id = wl_map_insert_new(&display->objects, proxy);
pthread_mutex_unlock(&display->mutex);
return proxy;
@ -518,17 +517,16 @@ wl_display_connect_to_fd(int fd)
memset(display, 0, sizeof *display);
display->fd = fd;
wl_map_init(&display->objects);
wl_map_init(&display->objects, WL_MAP_CLIENT_SIDE);
wl_event_queue_init(&display->queue, display);
wl_list_init(&display->event_queue_list);
pthread_mutex_init(&display->mutex, NULL);
wl_map_insert_new(&display->objects, WL_MAP_CLIENT_SIDE, NULL);
wl_map_insert_new(&display->objects, NULL);
display->proxy.object.interface = &wl_display_interface;
display->proxy.object.id =
wl_map_insert_new(&display->objects,
WL_MAP_CLIENT_SIDE, display);
wl_map_insert_new(&display->objects, display);
display->proxy.display = display;
display->proxy.object.implementation = (void(**)(void)) &display_listener;
display->proxy.user_data = display;