xfree86: Fix event data alignment in inputtest driver

This fixes address sanitizer errors when running unit tests. The
additional copying may reduce performance by a small amount, but we
don't care about that because this driver is used for testing only.

Signed-off-by: Povilas Kanapickas <povilas@radix.lt>
This commit is contained in:
Povilas Kanapickas 2021-12-19 16:51:39 +02:00
parent 43e934a19f
commit 7d2014e7d5

View File

@ -856,39 +856,48 @@ read_input_from_connection(InputInfoPtr pInfo)
driver_data->buffer.valid_length += read_size;
while (1) {
xf86ITEventHeader *event_header;
xf86ITEventHeader event_header;
char *event_begin = driver_data->buffer.data + processed_size;
if (driver_data->buffer.valid_length - processed_size < sizeof(xf86ITEventHeader))
break;
event_header = (xf86ITEventHeader*) event_begin;
/* Note that event_begin pointer is not aligned, accessing it directly is
undefined behavior. We must use memcpy to copy the data to aligned data
area. Most compilers will optimize out this call out and use whatever
is most efficient to access unaligned data on a particular platform */
memcpy(&event_header, event_begin, sizeof(xf86ITEventHeader));
if (event_header->length >= EVENT_BUFFER_SIZE) {
if (event_header.length >= EVENT_BUFFER_SIZE) {
xf86IDrvMsg(pInfo, X_ERROR, "Received event with too long length: %d\n",
event_header->length);
event_header.length);
teardown_client_connection(pInfo);
return;
}
if (driver_data->buffer.valid_length - processed_size < event_header->length)
if (driver_data->buffer.valid_length - processed_size < event_header.length)
break;
if (is_supported_event(event_header->type)) {
int expected_event_size = get_event_size(event_header->type);
if (is_supported_event(event_header.type)) {
int expected_event_size = get_event_size(event_header.type);
if (event_header->length != expected_event_size) {
if (event_header.length != expected_event_size) {
xf86IDrvMsg(pInfo, X_ERROR, "Unexpected event length: was %d bytes, "
"expected %d (event type: %d)\n",
event_header->length, expected_event_size,
(int) event_header->type);
event_header.length, expected_event_size,
(int) event_header.type);
teardown_client_connection(pInfo);
return;
}
handle_event(pInfo, (xf86ITEventAny*) event_begin);
/* We could use event_begin pointer directly, but we want to ensure correct
data alignment (if only so that address sanitizer does not complain) */
xf86ITEventAny event_data;
memset(&event_data, 0, sizeof(event_data));
memcpy(&event_data, event_begin, event_header.length);
handle_event(pInfo, &event_data);
}
processed_size += event_header->length;
processed_size += event_header.length;
}
if (processed_size > 0) {