summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2017-01-24 12:07:21 -0600
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2017-01-25 14:59:02 +0200
commitde908658945ef8e13b27b32a7a69f14b3f9356df (patch)
tree97fa9babfbf00698b99e6fc98a56a9bd4d942734
parentefae9532e82e1faeb737fe0d3cf5932026ce1e6f (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.c35
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]);