summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2012-09-10 11:20:35 +0200
committerKristian Høgsberg <krh@bitplanet.net>2012-09-10 21:44:47 -0400
commit9fe135c46f2457d6dc694e4c02d2defeab6986b0 (patch)
tree4f05dc916c00791e77ab69eb00eb1181c4e5f595
parent397a0c6ada56e4330ebf2bc662010ca8d32a2c73 (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.c12
-rw-r--r--src/wayland-server.h2
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);