Closed Drawishe closed 3 months ago
Hi @Drawishe ,
thank you for the report!
I've looked into the code and I'm not sure how stack overflow happened there - we add limit (-1) in _cupsSNMPWrite()
and _cupsSNMPStringToOID()
into oid:
_cupsSNMPStringToOID():
502 /*
503 * Terminate the end of the OID array and return...
504 */
505
506 dstptr[1] = -1;
507
508 return (dst);
_cupsSNMPWrite():
658 for (i = 0; oid[i] >= 0 && i < (CUPS_SNMP_MAX_OID - 1); i ++)
659 packet.object_name[i] = oid[i];
660 packet.object_name[i] = -1;
The check in _cupsSNMPWrite() protects from larger oids than CUPS_SNMP_MAX_OID as well.
Then packet
is sent to asn1_encode_snmp()
:
669
670 bytes = asn1_encode_snmp(buffer, sizeof(buffer), &packet);
671
and its packet->object_name
is used oid - it looks to me that the array cannot be bigger than 128 and it has -1 as last member.
Can you explain when the stack overflow happens?
Hello, @zdohnal!
Thank you for your comment.
I spent some time to debug this issue, and get some information.
In this case, the number of array elements oid == 0.
The asn1_size_oid()
function checks the element oid[1]
.
https://github.com/OpenPrinting/cups/blob/462e85146773486be3bf82af5e99a89caeb188c3/cups/snmp.c#L1635
In this case, oid[1]
== 0, because the packet structure is completely filled with 0 before creating SNMP message.
https://github.com/OpenPrinting/cups/blob/462e85146773486be3bf82af5e99a89caeb188c3/cups/snmp.c#L649
I think, we also need to check the oid[0]
for it's value.
Ok, I looked into more...
The reason why the array does have limit on the first number is because oid from file is invalid (there are no dots and the number is too large, so integer overflows).
Since the affected function is not public and accessible only via _cupsSNMPWrite()
(another private function), so we can only ensure the input is valid for the function. OID is static arrays in most cases, the only cases when we load it from input it is in the test and when reading from side channel - both can be fixed by _cupsSNMPStringtoOID()
.
I'll file PR about it.
Describe the bug
I have found Stack-Buffer-overflow error with cups upstream version (462e851), using unittest testsnmp.c as a harness for fuzzing. Here are the files needed to reproduce the bug:
repro.tar.gz
To Reproduce
Steps to reproduce the behaviour:
move given
argv-fuzz-inl.h
andcrash.input
files in cups/ directorybuild project with clang and ASAN
testsnmp.c
fileAdd given library
Add
AFL_INIT_ARGV()
macro in the beggining of main functionThis error is caused by the lack of checking when executing the for cycle. The for cycle ends when the value of
*oid
< 0. In this case, there are no conditions for cycle termination, which causes a stack-buffer-overflow.https://github.com/OpenPrinting/cups/blob/462e85146773486be3bf82af5e99a89caeb188c3/cups/snmp.c#L1638-L1640
Solution:
A possible solution to the problem is to add a counter to the for loop that terminates the loop when the limit number of oid elements is reached (In testsnmp.c this value == 128).
System information: