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>
This commit is contained in:
David Herrmann 2012-09-10 11:20:35 +02:00 committed by Kristian Høgsberg
parent 397a0c6ada
commit 9fe135c46f
2 changed files with 9 additions and 5 deletions

View file

@ -387,23 +387,27 @@ wl_client_get_credentials(struct wl_client *client,
*gid = client->ucred.gid; *gid = client->ucred.gid;
} }
WL_EXPORT void WL_EXPORT uint32_t
wl_client_add_resource(struct wl_client *client, wl_client_add_resource(struct wl_client *client,
struct wl_resource *resource) struct wl_resource *resource)
{ {
if (resource->object.id == 0) if (resource->object.id == 0) {
resource->object.id = resource->object.id =
wl_map_insert_new(&client->objects, wl_map_insert_new(&client->objects,
WL_MAP_SERVER_SIDE, resource); WL_MAP_SERVER_SIDE, resource);
else if (wl_map_insert_at(&client->objects, } else if (wl_map_insert_at(&client->objects,
resource->object.id, resource) < 0) resource->object.id, resource) < 0) {
wl_resource_post_error(client->display_resource, wl_resource_post_error(client->display_resource,
WL_DISPLAY_ERROR_INVALID_OBJECT, WL_DISPLAY_ERROR_INVALID_OBJECT,
"invalid new id %d", "invalid new id %d",
resource->object.id); resource->object.id);
return 0;
}
resource->client = client; resource->client = client;
wl_signal_init(&resource->destroy_signal); wl_signal_init(&resource->destroy_signal);
return resource->object.id;
} }
WL_EXPORT struct wl_resource * WL_EXPORT struct wl_resource *

View file

@ -354,7 +354,7 @@ void wl_resource_post_no_memory(struct wl_resource *resource);
#include "wayland-server-protocol.h" #include "wayland-server-protocol.h"
void uint32_t
wl_client_add_resource(struct wl_client *client, wl_client_add_resource(struct wl_client *client,
struct wl_resource *resource); struct wl_resource *resource);