ei: better protocol checking for invalid messages

This commit is contained in:
Peter Hutterer 2023-02-20 13:46:40 +10:00
parent dd5bc6b6e7
commit 1a21c4854b
4 changed files with 49 additions and 11 deletions

View file

@ -144,6 +144,10 @@ handle_msg_name(struct ei_device *device, const char *name)
static struct brei_result *
handle_msg_capabilities(struct ei_device *device, uint32_t caps)
{
if (device->capabilities != 0)
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"EIS sent the device capabilities twice");
ei_device_set_capabilities(device, caps);
return NULL;
}
@ -151,6 +155,9 @@ handle_msg_capabilities(struct ei_device *device, uint32_t caps)
static struct brei_result *
handle_msg_type(struct ei_device *device, enum ei_device_type type)
{
if (device->type != 0)
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"EIS sent the device type twice");
ei_device_set_type(device, type);
return NULL;
}
@ -158,7 +165,11 @@ handle_msg_type(struct ei_device *device, enum ei_device_type type)
static struct brei_result *
handle_msg_dimensions(struct ei_device *device, uint32_t width, uint32_t height)
{
if (ei_device_get_width(device) != 0 || ei_device_get_height(device) != 0)
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"EIS sent the device type twice");
ei_device_set_size(device, width, height);
return NULL;
}
@ -179,6 +190,25 @@ static struct brei_result *
handle_msg_done(struct ei_device *device)
{
struct ei *ei = ei_device_get_context(device);
uint32_t width = ei_device_get_width(device);
uint32_t height = ei_device_get_height(device);
switch (ei_device_get_type(device)) {
case EI_DEVICE_TYPE_PHYSICAL:
if (width == 0 || height == 0)
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"missing width/height for physical device");
break;
case EI_DEVICE_TYPE_VIRTUAL:
if (width != 0 || height != 0)
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"no width/height allowed for virtual device");
break;
default:
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"Unsupported device type %ud", ei_device_get_type(device));
}
ei_device_added(device);
ei_queue_device_added_event(device);
@ -215,8 +245,8 @@ handle_msg_paused(struct ei_device *device)
#define DISCONNECT_IF_SENDER_CONTEXT(device_) do {\
struct ei *ei_ = ei_device_get_context(device_); \
if (ei_is_sender(ei_)) { \
log_bug_client(ei_, "Invalid event from receiver EIS context. Disconnecting"); \
return brei_result_new_from_neg_errno(-ECANCELED); \
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_MODE, \
"Invalid event from receiver EIS context. Disconnecting"); \
} \
} while(0)
@ -281,7 +311,8 @@ static struct brei_result *
handle_msg_pointer(struct ei_device *device, uint32_t id, uint32_t version)
{
if (device->pointer)
return brei_result_new_from_neg_errno(-EPROTO);
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"Duplicate ei_pointer interface object on device");
device->pointer = ei_pointer_new(device, id, version);
@ -292,7 +323,8 @@ static struct brei_result *
handle_msg_keyboard(struct ei_device *device, uint32_t id, uint32_t version)
{
if (device->keyboard)
return brei_result_new_from_neg_errno(-EPROTO);
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"Duplicate ei_keyboard interface object on device");
device->keyboard = ei_keyboard_new(device, id, version);
@ -303,7 +335,8 @@ static struct brei_result *
handle_msg_touchscreen(struct ei_device *device, uint32_t id, uint32_t version)
{
if (device->touchscreen)
return brei_result_new_from_neg_errno(-EPROTO);
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"Duplicate ei_touchscreen interface object on device");
device->touchscreen = ei_touchscreen_new(device, id, version);

View file

@ -84,7 +84,8 @@ static struct brei_result *
handle_msg_name(struct ei_seat *seat, const char * name)
{
if (seat->name != NULL)
return brei_result_new_from_neg_errno(-EPROTO);
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"EIS sent the seat name twice");
seat->name = xstrdup(name);
@ -95,7 +96,8 @@ static struct brei_result *
handle_msg_capabilities(struct ei_seat *seat, uint32_t capabilities)
{
if (seat->capabilities != 0)
return brei_result_new_from_neg_errno(-EPROTO);
return brei_result_new(EI_CONNECTION_DISCONNECT_REASON_PROTOCOL,
"EIS sent the seat capabilities twice");
seat->capabilities = capabilities;
return 0;

View file

@ -666,12 +666,15 @@ handle_msg_disconnected(struct ei_connection *connection, uint32_t reason, const
{
struct ei *ei = ei_connection_get_context(connection);
if (reason == EI_CONNECTION_DISCONNECT_REASON_DISCONNECTED)
if (reason == EI_CONNECTION_DISCONNECT_REASON_DISCONNECTED) {
log_info(ei, "Disconnected by EIS");
else
ei_disconnect(ei);
return NULL;
} else {
log_info(ei, "Disconnected after error: %s", explanation);
return brei_result_new(reason, "%s", explanation);
}
return brei_result_new_from_neg_errno(-ECANCELED);
}
static struct brei_result *

View file

@ -215,7 +215,7 @@ client_msg_release(struct eis_device *device)
if (!eis_client_is_sender(client_)) { \
struct eis *_ctx = eis_client_get_context(client_); \
log_bug_client(_ctx, "Invalid event from receiver ei context. Disconnecting client"); \
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_ERROR, "Invalid event from receiver ei context"); \
return brei_result_new(EIS_CONNECTION_DISCONNECT_REASON_MODE, "Invalid event from receiver ei context"); \
} \
} while(0)