diff options
author | David Herrmann <dh.herrmann@googlemail.com> | 2012-09-10 11:20:35 +0200 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2012-09-10 21:44:47 -0400 |
commit | 9fe135c46f2457d6dc694e4c02d2defeab6986b0 (patch) | |
tree | 4f05dc916c00791e77ab69eb00eb1181c4e5f595 | |
parent | 397a0c6ada56e4330ebf2bc662010ca8d32a2c73 (diff) |
wayland-server: return new ID in wl_client_add_resource()
wl_client_add_resource() used to return no error even though the new
resource wasn't added to the client. This currently makes it very easy to
DOS weston by simply posting thousands of "create_surface" requests with
an invalid ID. Weston simply assumes the wl_client_add_resource() request
succeeds but will never destroy the surface again as the "destroy" signal
is never called (because the surface isn't linked into the wl_map).
This change makes wl_client_add_resource() return the new ID of the added
object and 0 on failure. Servers (like weston) can now correctly
immediately destroy the surface when this call fails instead of leaving
the surface around and producing memory-leaks.
Instead of returning -1 on failure and 0 on success, I made it return the
new ID as this seems more appropriate. We can directly use it when calling
it with new_id==0.
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
-rw-r--r-- | src/wayland-server.c | 12 | ||||
-rw-r--r-- | src/wayland-server.h | 2 |
2 files changed, 9 insertions, 5 deletions
diff --git a/src/wayland-server.c b/src/wayland-server.c index 88e8433..416cec1 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -387,23 +387,27 @@ wl_client_get_credentials(struct wl_client *client, *gid = client->ucred.gid; } -WL_EXPORT void +WL_EXPORT uint32_t wl_client_add_resource(struct wl_client *client, struct wl_resource *resource) { - if (resource->object.id == 0) + if (resource->object.id == 0) { resource->object.id = wl_map_insert_new(&client->objects, WL_MAP_SERVER_SIDE, resource); - else if (wl_map_insert_at(&client->objects, - resource->object.id, resource) < 0) + } else if (wl_map_insert_at(&client->objects, + resource->object.id, resource) < 0) { wl_resource_post_error(client->display_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, "invalid new id %d", resource->object.id); + return 0; + } resource->client = client; wl_signal_init(&resource->destroy_signal); + + return resource->object.id; } WL_EXPORT struct wl_resource * diff --git a/src/wayland-server.h b/src/wayland-server.h index cd79801..3c56729 100644 --- a/src/wayland-server.h +++ b/src/wayland-server.h @@ -354,7 +354,7 @@ void wl_resource_post_no_memory(struct wl_resource *resource); #include "wayland-server-protocol.h" -void +uint32_t wl_client_add_resource(struct wl_client *client, struct wl_resource *resource); |