diff --git a/doc/publican/sources/Protocol.xml b/doc/publican/sources/Protocol.xml index 38243fa7..af5f437d 100644 --- a/doc/publican/sources/Protocol.xml +++ b/doc/publican/sources/Protocol.xml @@ -110,8 +110,9 @@ - The second has 2 parts of 16-bit. The upper 16-bits are the message - size in bytes, starting at the header (i.e. it has a minimum value of 8).The lower is the request/event opcode. + The second has 2 parts of 16 bits each. The upper 16 bits are the message + size in bytes, starting at the header (i.e. it has a minimum value of 8). + The lower is the request/event opcode. The size must be a multiple of 4. diff --git a/src/connection.c b/src/connection.c index e1b751ac..93f5a090 100644 --- a/src/connection.c +++ b/src/connection.c @@ -902,7 +902,14 @@ wl_connection_demarshal(struct wl_connection *connection, /* Space for sender_id and opcode */ if (size < 2 * sizeof *p) { - wl_log("message too short, invalid header\n"); + wl_log("message length %" PRIu32 " too short, invalid header\n", size); + wl_connection_consume(connection, size); + errno = EINVAL; + return NULL; + } + + if (size % sizeof *p) { + wl_log("message length %" PRIu32 " invalid, not multiple of 4 bytes", size); wl_connection_consume(connection, size); errno = EINVAL; return NULL; diff --git a/src/wayland-server.c b/src/wayland-server.c index 1d6be3ec..b7158244 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -400,6 +400,15 @@ wl_client_connection_data(int fd, uint32_t mask, void *data) if (len < size) break; + if ((size & 3) != 0) { + /* Post a better error than "invalid arguments" */ + wl_resource_post_error(client->display_resource, + WL_DISPLAY_ERROR_INVALID_METHOD, + "message length %u is not multiple of 4", + size); + break; + } + resource = wl_map_lookup(&client->objects, p[0]); resource_flags = wl_map_lookup_flags(&client->objects, p[0]); if (resource == NULL) {