|
|
39a9e2 |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
39a9e2 |
From: Frediano Ziglio <fziglio@redhat.com>
|
|
|
39a9e2 |
Date: Fri, 18 May 2018 11:41:57 +0100
|
|
|
39a9e2 |
Subject: [PATCH] Fix flexible array buffer overflow
|
|
|
39a9e2 |
|
|
|
39a9e2 |
This is kind of a DoS, possibly flexible array in the protocol
|
|
|
39a9e2 |
causes the network size check to be ignored due to integer overflows.
|
|
|
39a9e2 |
|
|
|
39a9e2 |
The size of flexible array is computed as (message_end - position),
|
|
|
39a9e2 |
then this size is added to the number of bytes before the array and
|
|
|
39a9e2 |
this number is used to check if we overflow initial message.
|
|
|
39a9e2 |
|
|
|
39a9e2 |
An example is:
|
|
|
39a9e2 |
|
|
|
39a9e2 |
message {
|
|
|
39a9e2 |
uint32 dummy[2];
|
|
|
39a9e2 |
uint8 data[] @end;
|
|
|
39a9e2 |
} LenMessage;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
which generated this (simplified remove useless code) code:
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
data__nelements = message_end - (start + 8);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
nw_size = 8 + data__nw_size;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
/* Check if message fits in reported side */
|
|
|
39a9e2 |
if (nw_size > (uintptr_t) (message_end - start)) {
|
|
|
39a9e2 |
return NULL;
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
Following code:
|
|
|
39a9e2 |
- data__nelements == message_end - (start + 8)
|
|
|
39a9e2 |
- data__nw_size == data__nelements == message_end - (start + 8)
|
|
|
39a9e2 |
- nw_size == 8 + data__nw_size == 8 + message_end - (start + 8) ==
|
|
|
39a9e2 |
8 + message_end - start - 8 == message_end -start
|
|
|
39a9e2 |
- the check for overflow is (nw_size > (message_end - start)) but
|
|
|
39a9e2 |
nw_size == message_end - start so the check is doing
|
|
|
39a9e2 |
((message_end - start) > (message_end - start)) which is always false.
|
|
|
39a9e2 |
|
|
|
39a9e2 |
If message_end - start < 8 then data__nelements (number of element
|
|
|
39a9e2 |
on the array above) computation generate an integer underflow that
|
|
|
39a9e2 |
later create a buffer overflow.
|
|
|
39a9e2 |
|
|
|
39a9e2 |
Add a check to make sure that the array starts before the message ends
|
|
|
39a9e2 |
to avoid the overflow.
|
|
|
39a9e2 |
|
|
|
39a9e2 |
Difference is:
|
|
|
39a9e2 |
diff -u save/generated_client_demarshallers1.c common/generated_client_demarshallers1.c
|
|
|
39a9e2 |
- - save/generated_client_demarshallers1.c 2018-06-22 22:13:48.626793919 +0100
|
|
|
39a9e2 |
+ + common/generated_client_demarshallers1.c 2018-06-22 22:14:03.408163291 +0100
|
|
|
39a9e2 |
@@ -225,6 +225,9 @@
|
|
|
39a9e2 |
uint64_t data__nelements;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 0) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 0);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -243,6 +246,9 @@
|
|
|
39a9e2 |
*free_message = nofree;
|
|
|
39a9e2 |
return data;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
+ error:
|
|
|
39a9e2 |
+ free(data);
|
|
|
39a9e2 |
+ return NULL;
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
static uint8_t * parse_msg_set_ack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
|
|
|
39a9e2 |
@@ -301,6 +307,9 @@
|
|
|
39a9e2 |
SpiceMsgPing *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 12) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 12);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -5226,6 +5235,9 @@
|
|
|
39a9e2 |
uint64_t cursor_data__nw_size;
|
|
|
39a9e2 |
uint64_t cursor_data__nelements;
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start2 + 22) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
cursor_data__nelements = message_end - (start2 + 22);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
cursor_data__nw_size = cursor_data__nelements;
|
|
|
39a9e2 |
@@ -5305,6 +5317,9 @@
|
|
|
39a9e2 |
uint64_t cursor_data__nw_size;
|
|
|
39a9e2 |
uint64_t cursor_data__nelements;
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start2 + 22) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
cursor_data__nelements = message_end - (start2 + 22);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
cursor_data__nw_size = cursor_data__nelements;
|
|
|
39a9e2 |
@@ -5540,6 +5555,9 @@
|
|
|
39a9e2 |
SpiceMsgPlaybackPacket *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 4) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 4);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -5594,6 +5612,9 @@
|
|
|
39a9e2 |
SpiceMsgPlaybackMode *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 8) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 8);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
diff -u save/generated_client_demarshallers.c common/generated_client_demarshallers.c
|
|
|
39a9e2 |
- - save/generated_client_demarshallers.c 2018-06-22 22:13:48.626793919 +0100
|
|
|
39a9e2 |
+ + common/generated_client_demarshallers.c 2018-06-22 22:14:03.004153195 +0100
|
|
|
39a9e2 |
@@ -225,6 +225,9 @@
|
|
|
39a9e2 |
uint64_t data__nelements;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 0) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 0);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -243,6 +246,9 @@
|
|
|
39a9e2 |
*free_message = nofree;
|
|
|
39a9e2 |
return data;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
+ error:
|
|
|
39a9e2 |
+ free(data);
|
|
|
39a9e2 |
+ return NULL;
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
static uint8_t * parse_msg_set_ack(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
|
|
|
39a9e2 |
@@ -301,6 +307,9 @@
|
|
|
39a9e2 |
SpiceMsgPing *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 12) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 12);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -6574,6 +6583,9 @@
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start2 + 2 + cursor_u__nw_size) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
cursor_data__nelements = message_end - (start2 + 2 + cursor_u__nw_size);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
cursor_data__nw_size = cursor_data__nelements;
|
|
|
39a9e2 |
@@ -6670,6 +6682,9 @@
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start2 + 2 + cursor_u__nw_size) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
cursor_data__nelements = message_end - (start2 + 2 + cursor_u__nw_size);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
cursor_data__nw_size = cursor_data__nelements;
|
|
|
39a9e2 |
@@ -6907,6 +6922,9 @@
|
|
|
39a9e2 |
SpiceMsgPlaybackPacket *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 4) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 4);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -6961,6 +6979,9 @@
|
|
|
39a9e2 |
SpiceMsgPlaybackMode *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 6) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 6);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -7559,6 +7580,9 @@
|
|
|
39a9e2 |
SpiceMsgTunnelSocketData *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 2) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 2);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -7840,6 +7864,9 @@
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* compressed_data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 1 + u__nw_size) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
compressed_data__nelements = message_end - (start + 1 + u__nw_size);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
compressed_data__nw_size = compressed_data__nelements;
|
|
|
39a9e2 |
diff -u save/generated_server_demarshallers.c common/generated_server_demarshallers.c
|
|
|
39a9e2 |
- - save/generated_server_demarshallers.c 2018-06-22 22:13:48.627793944 +0100
|
|
|
39a9e2 |
+ + common/generated_server_demarshallers.c 2018-06-22 22:14:05.231208847 +0100
|
|
|
39a9e2 |
@@ -306,6 +306,9 @@
|
|
|
39a9e2 |
uint64_t data__nelements;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 0) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 0);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -324,6 +327,9 @@
|
|
|
39a9e2 |
*free_message = nofree;
|
|
|
39a9e2 |
return data;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
+ error:
|
|
|
39a9e2 |
+ free(data);
|
|
|
39a9e2 |
+ return NULL;
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
static uint8_t * parse_msgc_disconnecting(uint8_t *message_start, uint8_t *message_end, SPICE_GNUC_UNUSED int minor, size_t *size, message_destructor_t *free_message)
|
|
|
39a9e2 |
@@ -1259,6 +1265,9 @@
|
|
|
39a9e2 |
SpiceMsgcRecordPacket *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 4) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 4);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -1313,6 +1322,9 @@
|
|
|
39a9e2 |
SpiceMsgcRecordMode *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 6) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 6);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -1841,6 +1853,9 @@
|
|
|
39a9e2 |
SpiceMsgcTunnelSocketData *out;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 2) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
data__nelements = message_end - (start + 2);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
data__nw_size = data__nelements;
|
|
|
39a9e2 |
@@ -2057,6 +2072,9 @@
|
|
|
39a9e2 |
}
|
|
|
39a9e2 |
|
|
|
39a9e2 |
{ /* compressed_data */
|
|
|
39a9e2 |
+ if (SPICE_UNLIKELY((start + 1 + u__nw_size) > message_end)) {
|
|
|
39a9e2 |
+ goto error;
|
|
|
39a9e2 |
+ }
|
|
|
39a9e2 |
compressed_data__nelements = message_end - (start + 1 + u__nw_size);
|
|
|
39a9e2 |
|
|
|
39a9e2 |
compressed_data__nw_size = compressed_data__nelements;
|
|
|
39a9e2 |
|
|
|
39a9e2 |
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
|
|
|
39a9e2 |
---
|
|
|
39a9e2 |
spice-common/python_modules/demarshal.py | 1 +
|
|
|
39a9e2 |
1 file changed, 1 insertion(+)
|
|
|
39a9e2 |
|
|
|
39a9e2 |
diff --git a/spice-common/python_modules/demarshal.py b/spice-common/python_modules/demarshal.py
|
|
|
39a9e2 |
index 1ea131d..7172762 100644
|
|
|
39a9e2 |
--- a/spice-common/python_modules/demarshal.py
|
|
|
39a9e2 |
+++ b/spice-common/python_modules/demarshal.py
|
|
|
39a9e2 |
@@ -318,6 +318,7 @@ def write_validate_array_item(writer, container, item, scope, parent_scope, star
|
|
|
39a9e2 |
writer.assign(nelements, array.size)
|
|
|
39a9e2 |
elif array.is_remaining_length():
|
|
|
39a9e2 |
if element_type.is_fixed_nw_size():
|
|
|
39a9e2 |
+ writer.error_check("%s > message_end" % item.get_position())
|
|
|
39a9e2 |
if element_type.get_fixed_nw_size() == 1:
|
|
|
39a9e2 |
writer.assign(nelements, "message_end - %s" % item.get_position())
|
|
|
39a9e2 |
else:
|