[RFC wayland] wayland-server: assert instead of posting events with wrong client objects

Derek Foreman derekf at osg.samsung.com
Thu Dec 1 23:19:41 UTC 2016


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 <derekf at 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



More information about the wayland-devel mailing list