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>
This commit is contained in:
Derek Foreman 2017-01-24 12:07:21 -06:00 committed by Pekka Paalanen
parent efae9532e8
commit de90865894

View file

@ -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 static void
handle_array(struct wl_resource *resource, uint32_t opcode, handle_array(struct wl_resource *resource, uint32_t opcode,
union wl_argument *args, union wl_argument *args,
@ -179,6 +209,11 @@ handle_array(struct wl_resource *resource, uint32_t opcode,
if (resource->client->error) if (resource->client->error)
return; return;
if (!verify_objects(resource, opcode, args)) {
resource->client->error = 1;
return;
}
closure = wl_closure_marshal(object, opcode, args, closure = wl_closure_marshal(object, opcode, args,
&object->interface->events[opcode]); &object->interface->events[opcode]);