[PATCH v5 wayland 3/3] wayland-server: log an error for events with wrong client objects

Derek Foreman derekf at osg.samsung.com
Tue Jan 24 18:07:21 UTC 2017


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 at humanoriented.com>
Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>
Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
---

This started life as an assert, became an abort, and now it's a log
and disconnect.  Log and disconnect is already how we manage nullable
violation on the compositor side, so I'm hoping it won't be too
controversial.

For EFL clients the disconnect is recoverable under some circumstances with
our session recovery protocol, but the current client-abort()s behaviour
is not.

Changes from v1:
uses get_next_arguemnts and arg_count_for_signature instead of a bespoke
implementation.

Changes from v2:
Tests new_id objects as well
logs and disconnects instead of assert()/abort()
superficial changes to the log text

Changes from v3:
Actually printing the interface name and message name make this
useful for debugging - instead of actually less informative
than it was with a client side error.

Changes from v4:
Rebased on top of previous two patches in this series.

There's a test case for this in patchwork as well, but I've not re-sent it
since it's unchanged.

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

diff --git a/src/wayland-server.c b/src/wayland-server.c
index 7e26aa0..824bc2f 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -163,6 +163,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,
@@ -174,6 +204,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]);
 
-- 
2.11.0



More information about the wayland-devel mailing list