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
kill itself.

It's intended that the compositor killing itself be easier to debug
than the client killing itself for something that it's completely
innocent of.

Signed-off-by: Derek Foreman <der...@osg.samsung.com>
---

Recently caught a bug in Enlightenment where we were posting keyboard enter
events with a surface from another client.  In most cases this results in
the client disconnecting itself due to the target object being the wrong type.
It might be more hilarious if the types just magically happened to match.

Are we interested in this level of footgun protection?

It's also been suggested that this might be better if conditional on
WAYLAND_DEBUG.

 src/wayland-server.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 9d7d9c1..bf1719a 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -160,6 +160,27 @@ log_closure(struct wl_resource *resource,
        }
 }
 
+static bool
+clients_match(struct wl_resource *resource, uint32_t opcode,
+             union wl_argument *args)
+{
+       struct wl_object *object = &resource->object;
+       const char *sig = object->interface->events[opcode].signature;
+
+       for (;*sig;sig++) {
+               if (*sig == '?')
+                       continue;
+
+               if (*sig == 'o') {
+                       struct wl_resource *res = (struct wl_resource *) 
(args->o);
+                       if (res && res->client != resource->client)
+                               return false;
+               }
+               args++;
+       }
+       return true;
+}
+
 WL_EXPORT void
 wl_resource_post_event_array(struct wl_resource *resource, uint32_t opcode,
                             union wl_argument *args)
@@ -167,6 +188,7 @@ wl_resource_post_event_array(struct wl_resource *resource, 
uint32_t opcode,
        struct wl_closure *closure;
        struct wl_object *object = &resource->object;
 
+       assert(clients_match(resource, opcode, args));
        closure = wl_closure_marshal(object, opcode, args,
                                     &object->interface->events[opcode]);
 
@@ -206,6 +228,7 @@ wl_resource_queue_event_array(struct wl_resource *resource, 
uint32_t opcode,
        struct wl_closure *closure;
        struct wl_object *object = &resource->object;
 
+       assert(clients_match(resource, opcode, args));
        closure = wl_closure_marshal(object, opcode, args,
                                     &object->interface->events[opcode]);
 
-- 
2.10.2

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to