mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2026-02-11 07:10:29 +01:00
libei: check incoming objects' version for correctness
If the server sends a protocol version higher than we support, fail.
This commit is contained in:
parent
f081e8e79f
commit
c99f4ffa2c
5 changed files with 28 additions and 0 deletions
|
|
@ -402,33 +402,41 @@ handle_msg_interface(struct ei_device *device, object_id_t id, const char *name,
|
|||
{
|
||||
DISCONNECT_IF_INVALID_ID(device, id);
|
||||
|
||||
struct ei *ei = ei_device_get_context(device);
|
||||
|
||||
if (streq(name, EI_POINTER_INTERFACE_NAME)) {
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_pointer, id, version);
|
||||
if (device->pointer)
|
||||
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Duplicate ei_pointer interface object on device");
|
||||
device->pointer = ei_pointer_new(device, id, version);
|
||||
} else if (streq(name, EI_POINTER_ABSOLUTE_INTERFACE_NAME)) {
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_pointer_absolute, id, version);
|
||||
if (device->pointer_absolute)
|
||||
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Duplicate ei_pointer_absolute interface object on device");
|
||||
device->pointer_absolute = ei_pointer_absolute_new(device, id, version);
|
||||
} else if (streq(name, EI_SCROLL_INTERFACE_NAME)) {
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_scroll, id, version);
|
||||
if (device->scroll)
|
||||
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Duplicate ei_scroll interface object on device");
|
||||
device->scroll = ei_scroll_new(device, id, version);
|
||||
} else if (streq(name, EI_BUTTON_INTERFACE_NAME)) {
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_button, id, version);
|
||||
if (device->button)
|
||||
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Duplicate ei_button interface object on device");
|
||||
device->button = ei_button_new(device, id, version);
|
||||
} else if (streq(name, EI_KEYBOARD_INTERFACE_NAME)) {
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_keyboard, id, version);
|
||||
if (device->keyboard)
|
||||
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Duplicate ei_keyboard interface object on device");
|
||||
|
||||
device->keyboard = ei_keyboard_new(device, id, version);
|
||||
} else if (streq(name, EI_TOUCHSCREEN_INTERFACE_NAME)) {
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_touchscreen, id, version);
|
||||
if (device->touchscreen)
|
||||
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
|
||||
"Duplicate ei_touchscreen interface object on device");
|
||||
|
|
|
|||
|
|
@ -169,6 +169,8 @@ handle_msg_connection(struct ei_handshake *setup, uint32_t serial, object_id_t i
|
|||
/* we're done with our handshake, drop it */
|
||||
ei_handshake_unref(steal(&ei->handshake));
|
||||
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_handshake, id, version);
|
||||
|
||||
ei->connection = ei_connection_new(ei, id, version);
|
||||
ei->state = EI_STATE_CONNECTING;
|
||||
ei_update_serial(ei, serial);
|
||||
|
|
|
|||
|
|
@ -244,3 +244,13 @@ ei_log_msg_va(struct ei *ei,
|
|||
ei_log_msg((T_), EI_LOG_PRIORITY_ERROR, __FILE__, __LINE__, __func__, "🪳 libei bug: " __VA_ARGS__)
|
||||
#define log_bug_client(T_, ...) \
|
||||
ei_log_msg((T_), EI_LOG_PRIORITY_ERROR, __FILE__, __LINE__, __func__, "🪲 Bug: " __VA_ARGS__)
|
||||
|
||||
#define DISCONNECT_IF_INVALID_VERSION(ei_, intf_, id_, version_) do { \
|
||||
struct ei *_ei = (ei_); \
|
||||
uint32_t _version = (version_); \
|
||||
uint64_t _id = (id_); \
|
||||
if (_ei->interface_versions.intf_ < _version) { \
|
||||
log_bug(ei_, "Received invalid version %u for object id %#" PRIx64 ". Disconnecting", _version, _id); \
|
||||
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL, "Received invalid version %u for object id %#" PRIx64 ".", _version, _id); \
|
||||
} \
|
||||
} while(0)
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ handle_msg_device(struct ei_seat *seat, object_id_t id, uint32_t version)
|
|||
|
||||
struct ei *ei = ei_seat_get_context(seat);
|
||||
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_device, id, version);
|
||||
|
||||
log_debug(ei, "Added device %#" PRIx64 "@v%u", id, version);
|
||||
/* device is in the seat's device list */
|
||||
struct ei_device *device = ei_device_new(seat, id, version);
|
||||
|
|
|
|||
|
|
@ -590,6 +590,9 @@ handle_msg_seat(struct ei_connection *connection, object_id_t seat_id, uint32_t
|
|||
DISCONNECT_IF_INVALID_ID(connection, seat_id);
|
||||
|
||||
struct ei *ei = ei_connection_get_context(connection);
|
||||
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_seat, seat_id, version);
|
||||
|
||||
struct ei_seat *seat = ei_seat_new(ei, seat_id, version);
|
||||
|
||||
/* We might get the seat event before our callback finished, so make sure
|
||||
|
|
@ -679,6 +682,9 @@ handle_msg_ping(struct ei_connection *connection, object_id_t id, uint32_t vers
|
|||
DISCONNECT_IF_INVALID_ID(connection, id);
|
||||
|
||||
struct ei *ei = ei_connection_get_context(connection);
|
||||
|
||||
DISCONNECT_IF_INVALID_VERSION(ei, ei_pingpong, id, version);
|
||||
|
||||
_unref_(ei_pingpong) *pingpong = ei_pingpong_new_for_id(ei, id, version);
|
||||
|
||||
ei_pingpong_request_done(pingpong, 0);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue