diff options
author | Jason Ekstrand <jason@jlekstrand.net> | 2013-07-02 14:57:10 -0400 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-07-02 17:01:46 -0400 |
commit | a09d7f0d60143653f0bd3e569e8bc4fcef73eeba (patch) | |
tree | 4397f24aef3d00267757dd8c6ca06e5b1e175968 | |
parent | 4917a967bdcd33b7ad264af9c984c3957d87f569 (diff) |
wayland-server: Verify request versions before invoking handler
This commit provides a layer of protection for the compositor in the form
of message version checking. We track version information in the
wl_resource and now use this version information to verify that a request
exists in that protocol version before invoking it. This way libwayland
won't accidentally invoke a request that does not exist and thereby cause
the compositor to crash.
Signed-off-by: Jason Ekstrand <jason@jlekstrand.net>
-rw-r--r-- | src/wayland-server.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/wayland-server.c b/src/wayland-server.c index 57770ab..bdacaee 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -211,6 +211,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) struct wl_closure *closure; const struct wl_message *message; uint32_t p[2]; + uint32_t resource_flags; int opcode, size; int len; @@ -247,6 +248,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) break; resource = wl_map_lookup(&client->objects, p[0]); + resource_flags = wl_map_lookup_flags(&client->objects, p[0]); if (resource == NULL) { wl_resource_post_error(client->display_resource, WL_DISPLAY_ERROR_INVALID_OBJECT, @@ -266,6 +268,19 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) } message = &object->interface->methods[opcode]; + if (!(resource_flags & WL_MAP_ENTRY_LEGACY) && + resource->version > 0 && + resource->version < wl_message_get_since(message)) { + wl_resource_post_error(client->display_resource, + WL_DISPLAY_ERROR_INVALID_METHOD, + "invalid method %d, object %s@%u", + opcode, + object->interface->name, + object->id); + break; + } + + closure = wl_connection_demarshal(client->connection, size, &client->objects, message); len -= size; |