This is kind of a DoS, possibly flexible array in the protocol
causes the network size check to be ignored due to integer overflows.
The size of flexible array is computed as (message_end - position),
then this size is added to the number of bytes before the array and
this number is used to check if we overflow initial message.
An example is:
message {
uint32 dummy[2];
uint8 data[] @end;
} LenMessage;
which generated this (simplified remove useless code) code:
{ /* data */
data__nelements = message_end - (start + 8);
data__nw_size = data__nelements;
}
nw_size = 8 + data__nw_size;
/* Check if message fits in reported side */
if (nw_size > (uintptr_t) (message_end - start)) {
return NULL;
}
Following code:
- data__nelements == message_end - (start + 8)
- data__nw_size == data__nelements == message_end - (start + 8)
- nw_size == 8 + data__nw_size == 8 + message_end - (start + 8) ==
8 + message_end - start - 8 == message_end -start
- the check for overflow is (nw_size > (message_end - start)) but
nw_size == message_end - start so the check is doing
((message_end - start) > (message_end - start)) which is always false.
If message_end - start < 8 then data__nelements (number of element
on the array above) computation generate an integer underflow that
later create a buffer overflow.
Add a check to make sure that the array starts before the message ends
to avoid the overflow.
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
[Salvatore Bonaccorso: Drop generated diff from commit messages causing
problem when applying with quilt. Remove addition to testsuite]
Gbp-Pq: Name Fix-flexible-array-buffer-overflow.patch
writer.assign(nelements, array.size)
elif array.is_remaining_length():
if element_type.is_fixed_nw_size():
+ writer.error_check("%s > message_end" % item.get_position())
if element_type.get_fixed_nw_size() == 1:
writer.assign(nelements, "message_end - %s" % item.get_position())
else: