Stack-buffer-overflow in candump_write_packet
Description:
A stack-buffer-overflow vulnerability has been identified in Wireshark 4.0.5's candump_write_packet
function. This issue occurs when processing a specially crafted payload, which results in a crash and potentially code execution.
Tested on: Ubuntu 22.04.2 LTS
Steps to reproduce:
- Download and install Wireshark 4.0.5
- Run
tshark -r trigger
Result:
$ xxd -g1 trigger
00000000: 28 30 2e 30 29 09 30 09 30 30 30 23 52 39 (0.0).0.000#R9
$ tshark -r trigger
*** buffer overflow detected ***: terminated
Aborted
# After recompiling with "CANDUMP_DEBUG"
$ tshark -r trigger
candump_parse: Trying candump file decoder
candump_parse: Starting parser at offset 0
run_candump_parser: Starting parsing
yy_reduce: read message
run_candump_parser: Done (0)
candump_parse: Success
candump_open: This is our file
candump_read: Try reading at offset 0
candump_parse: Trying candump file decoder
candump_parse: Starting parser at offset 0
run_candump_parser: Starting parsing
yy_reduce: read message
run_candump_parser: Done (0)
candump_parse: Success
candump_read: Stopped at offset 14
*** buffer overflow detected ***: terminated
Aborted
The hexdump output shows the contents of the trigger file, which contains data that will cause the buffer overflow when parsed by Wireshark.
Technical details:
The issue can be traced back to the candump_write_packet
function in the wiretap/candump.c
file. The ASAN report indicates a WRITE operation of size 9 at address 0x7fffffffdb88
, which overflows the can_frame.sroa.660
variable in the stack.
The root cause of the vulnerability appears to be the use of the memcpy function in the candump_write_packet
function at line 83. The memcpy function is called with a length value that is larger than the destination buffer, causing a buffer overflow:
#define CAN_MAX_DLEN 8
typedef struct can_frame {
guint32 can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
guint8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
guint8 __pad; /* padding */
guint8 __res0; /* reserved / padding */
guint8 __res1; /* reserved / padding */
guint8 data[CAN_MAX_DLEN];
} can_frame_t;
memcpy(can_frame.data, msg->data.data, msg->data.length);
> b *candump_write_packet+612:
$rdi = 0x00007fffffffdd78 → 0x0000000000000000,
$rsi = 0x00007fffffffde12 → 0x0000000000000000,
→ $rdx = 0x0000000000000009
→ 0x42ba84 <candump_write_packet+612> call 0x406f30 <memcpy@plt>
The can_frame structure is used to store CAN (Controller Area Network) frames, including the CAN ID, data length code (DLC), and the actual data. The issue here is that msg->data.length
is 9, which is larger than the size of the destination buffer can_frame.data
(8 bytes). This results in a buffer overflow when memcpy tries to copy 9 bytes from the source buffer to the destination buffer, which can only accommodate 8 bytes.
Mitigation:
To address this vulnerability, it is necessary to add a check before the memcpy call to ensure that the length of the source data does not exceed the size of the destination buffer:
if (msg->data.length <= CAN_MAX_DLEN)
memcpy(can_frame.data, msg->data.data, msg->data.length);
I've tested the proposed patch and confirmed that it successfully processes the trigger file without causing a buffer overflow. If you would like me to submit a pull request with the implemented fix, please let me know and I will be happy to contribute.
Attachments:
- Trigger file
- ASAN Output
- GDB Backtrace
I'd also like to request a CVE ID for this vulnerability.
Please let me know if you need any additional information or assistance in addressing this vulnerability.
Regards,
Huáscar