From 9fe135c46f2457d6dc694e4c02d2defeab6986b0 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 10 Sep 2012 11:20:35 +0200 Subject: [PATCH] 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 --- src/wayland-server.c | 12 ++++++++---- 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); -- 2.7.4