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. Signed-off-by: Derek Foreman <der...@osg.samsung.com> --- This started life as an assert, became an abort, and now it's a log and disconnect. Log and disconnect is already how we manage nullable violation on the compositor side, so I'm hoping it won't be too controversial. For EFL clients the disconnect is recoverable under some circumstances with our session recovery protocol, but the current client-abort()s behaviour is not. Changes from v1: uses get_next_arguemnts and arg_count_for_signature instead of a bespoke implementation. Changes from v2: Tests new_id objects as well logs and disconnects instead of assert()/abort() superficial changes to the log text src/wayland-server.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/wayland-server.c b/src/wayland-server.c index 9d7d9c1..d9c7750 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -160,6 +160,35 @@ 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 an event for a different " + "client.\n"); + return false; + } + } + } + return true; +} + WL_EXPORT void wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode, union wl_argument *args) @@ -167,6 +196,10 @@ wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode, struct wl_closure *closure; struct wl_object *object = &resource->object; + if (!verify_objects(resource, opcode, args)) { + resource->client->error = 1; + return; + } closure = wl_closure_marshal(object, opcode, args, &object->interface->events[opcode]); @@ -206,6 +239,10 @@ wl_resource_queue_event_array(struct wl_resource *resource, uint32_t opcode, struct wl_closure *closure; struct wl_object *object = &resource->object; + if (!verify_objects(resource, opcode, args)) { + resource->client->error = 1; + return; + } closure = wl_closure_marshal(object, opcode, args, &object->interface->events[opcode]); -- 2.11.0 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel