From de908658945ef8e13b27b32a7a69f14b3f9356df Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Tue, 24 Jan 2017 12:07:21 -0600 Subject: wayland-server: log an error for events with wrong client objects Check that all the objects in an event belong to the same client as the resource posting it. This prevents a compositor from accidentally mixing client objects and posting an event that causes a client to abort with a cryptic message. Instead the client will now be disconnected as it is when the compositor tries to send a null for a non-nullable object, and a log message will be printed by the compositor. Reviewed-by: Yong Bakos Reviewed-by: Bryce Harrington Signed-off-by: Derek Foreman Reviewed-by: Pekka Paalanen --- src/wayland-server.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/wayland-server.c b/src/wayland-server.c index 0a5eacb..cdd46fa 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -168,6 +168,36 @@ log_closure(struct wl_resource *resource, } } +static bool +verify_objects(struct wl_resource *resource, uint32_t opcode, + union wl_argument *args) +{ + struct wl_object *object = &resource->object; + const char *signature = object->interface->events[opcode].signature; + struct argument_details arg; + struct wl_resource *res; + int count, i; + + count = arg_count_for_signature(signature); + for (i = 0; i < count; i++) { + signature = get_next_argument(signature, &arg); + switch (arg.type) { + case 'n': + case 'o': + res = (struct wl_resource *) (args[i].o); + if (res && res->client != resource->client) { + wl_log("compositor bug: The compositor " + "tried to use an object from one " + "client in a '%s.%s' for a different " + "client.\n", object->interface->name, + object->interface->events[opcode].name); + return false; + } + } + } + return true; +} + static void handle_array(struct wl_resource *resource, uint32_t opcode, union wl_argument *args, @@ -179,6 +209,11 @@ handle_array(struct wl_resource *resource, uint32_t opcode, if (resource->client->error) return; + if (!verify_objects(resource, opcode, args)) { + resource->client->error = 1; + return; + } + closure = wl_closure_marshal(object, opcode, args, &object->interface->events[opcode]); -- cgit v1.2.3