Description / Steps to reproduce the issue
Impact
A malformed packet can trigger memory corruption in the kernel leading to a system crash or potentially arbitrary code execution in the kernel.
Description
The CAN driver for the CTU CAN FD IP Core connected to the NuttX device via a PCI / PCI Express (PCIe) bus shows a lack of consideration for malformed data, assuming the CAN frames are always correct.
begin_packed_struct struct ctucanfd_frame_fmt_s
{
uint32_t dlc:4; /* DLC */
...
uint32_t rwcnt:5; /* Size without FRAME_FORMAT WORD */
...
uint32_t _reserved:4; /* Reserved */
} end_packed_struct;
begin_packed_struct struct ctucanfd_frame_s
{
struct ctucanfd_frame_fmt_s fmt; /* Frame format */
...
} end_packed_struct;
The size of struct ctucanfd_frame_s is 84 bytes, therefore, in the following code snippet, the buff array used by the ctucanfd_chardev_receive() has 21 uint32_t elements.
The code uses ctucanfd_getreg() to read the first four bytes from the CAN bus line into the ctucanfd_frame_s structure (populates fmt structure member). Immediately after, it uses the data read in frame->fmt.rwcnt without validation in the for loop. The attacker controls the content, and rwcnt structure member is 5 bits long therefore it can store a maximum value of 25 - 1 = 31. Since the length of the buff array is 21 elements and attackers can write 10 uint32_t additional elements, they can cause a 40-byte overflow of buff array. Note that the attacker can also control the content retrieved in the overflowing bytes.
/*****************************************************************************
* Name: ctucanfd_chardev_receive
* Description: Receive CAN frame
*****************************************************************************/
static void ctucanfd_chardev_receive(FAR struct ctucanfd_can_s *priv)
{
FAR struct can_dev_s *dev = (FAR struct can_dev_s *)priv;
FAR struct ctucanfd_frame_s *frame;
struct can_hdr_s hdr;
uint32_t buff[sizeof(struct ctucanfd_frame_s) / 4];
...
uint32_t regval = 0;
memset(&hdr, 0, sizeof(hdr));
....
/* We use a pointer to buffer to avoid an unaligned pointer compiler errors */
frame = (struct ctucanfd_frame_s *)&buff;
/* RX buffer in automatic mode */ // NCC Group read the 4-byte "fmt" element
buff[0] = ctucanfd_getreg(priv, CTUCANFD_RXDATA);
/* Read the rest of data */
for (i = 0; i < frame->fmt.rwcnt; i++) // NCC Group: uses the size without checking
{
buff[i + 1] = ctucanfd_getreg(priv, CTUCANFD_RXDATA); // NCC Group buffer overflow
}
There is a similar issue in ctucanfd_sock_recv(), it is not presented here due to brevity.
Recommendation
Ensure frame->fmt.rwcnt is 21 or less before it is used in the for loop.
On which OS does this issue occur?
[OS: Linux]
What is the version of your OS?
Ubuntu 24.04
NuttX Version
master
Issue Architecture
[Arch: all]
Issue Area
[Area: Debugging], [Area: Drivers]
Host information
N/A
Verification
Description / Steps to reproduce the issue
Impact
A malformed packet can trigger memory corruption in the kernel leading to a system crash or potentially arbitrary code execution in the kernel.
Description
The CAN driver for the CTU CAN FD IP Core connected to the NuttX device via a PCI / PCI Express (PCIe) bus shows a lack of consideration for malformed data, assuming the CAN frames are always correct.
The size of
struct ctucanfd_frame_sis 84 bytes, therefore, in the following code snippet, thebuffarray used by thectucanfd_chardev_receive()has 21uint32_telements.The code uses
ctucanfd_getreg()to read the first four bytes from the CAN bus line into thectucanfd_frame_sstructure (populatesfmtstructure member). Immediately after, it uses the data read inframe->fmt.rwcntwithout validation in theforloop. The attacker controls the content, andrwcntstructure member is 5 bits long therefore it can store a maximum value of 25 - 1 = 31. Since the length of thebuffarray is 21 elements and attackers can write 10uint32_tadditional elements, they can cause a 40-byte overflow ofbuffarray. Note that the attacker can also control the content retrieved in the overflowing bytes.There is a similar issue in
ctucanfd_sock_recv(), it is not presented here due to brevity.Recommendation
Ensure
frame->fmt.rwcntis 21 or less before it is used in theforloop.On which OS does this issue occur?
[OS: Linux]
What is the version of your OS?
Ubuntu 24.04
NuttX Version
master
Issue Architecture
[Arch: all]
Issue Area
[Area: Debugging], [Area: Drivers]
Host information
N/A
Verification