diff options
author | Derek Foreman <derekf@osg.samsung.com> | 2017-01-24 12:07:21 -0600 |
---|---|---|
committer | Pekka Paalanen <pekka.paalanen@collabora.co.uk> | 2017-01-25 14:59:02 +0200 |
commit | de908658945ef8e13b27b32a7a69f14b3f9356df (patch) | |
tree | 97fa9babfbf00698b99e6fc98a56a9bd4d942734 | |
parent | efae9532e82e1faeb737fe0d3cf5932026ce1e6f (diff) |
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 <ybakos@humanoriented.com>
Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
-rw-r--r-- | src/wayland-server.c | 35 |
1 files changed, 35 insertions, 0 deletions
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]); |