Skip to content

can: can_mcux_flexcan.c allows a mailbox overrun resulting in an imprecise data bus fault #92798

Open
@MichaelFeistETC

Description

@MichaelFeistETC

Describe the bug

I'm on commit hash:

can_mcux_flexcan.c lacks proper bounds checking to ensure that send calls don't overrun outside of the area allocated by the flexcan peripheral for message buffers.

On line 737 of can_mcux_flexcan.c inside of mcux_flexcan_send, there is this section of code:

for (alloc = 0; alloc < MCUX_FLEXCAN_MAX_TX; alloc++) {
	if (!atomic_test_and_set_bit(data->tx_allocs, alloc)) {
		break;
	}
}

data->tx_cbs[alloc].function = callback;
data->tx_cbs[alloc].arg = user_data;
xfer.mbIdx = ALLOC_IDX_TO_TXMB_IDX(alloc);

As you can see, the driver simply iterates from 0 to MCUX_FLEXCAN_MAX_TX. MCUX_FLEXCAN_MAX_TX is set by the following:

#define MCUX_FLEXCAN_MAX_TX (MCUX_FLEXCAN_MAX_MB - MCUX_FLEXCAN_MAX_RX)
#define MCUX_FLEXCAN_MAX_MB FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0)
#define FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(x) (64)
#define MCUX_FLEXCAN_MAX_RX (CONFIG_CAN_MAX_FILTER + RX_START_IDX)

However, if the peripheral is configured to use 64 byte message buffers, a maximum of 64 buffers is wrong.

From the datasheet, the max message buffer would be 13:

Image

Additionally, even if this max were set correctly, it doesn't seem great to just assume we will have an open buffer. In the case of no open buffer, this code just assumes the last one as the buffer to use. Really, this code should error out if it can't find an open buffer.

Regardless, alloc ends up being set incorrectly and eventually triggers a data bus error within the FLEXCAN_SetFDTxMbConfig call when it tries to access memory outside of the message buffer space.

In my case, this is always when it hits mailbox 14. It's probably unlikely to hit this if your CAN bus is operating normally as you won't reach the higher mailbox numbers. However, when the CAN peripheral is in an error state, the mailboxes just stack up until you overflow.

Regression

  • This is a regression.

Steps to reproduce

Enable CAN FD on the can_mcux_flexcan.c driver, put the CAN bus into an error state so that mailboxes are not being cleared (not strictly necessary, but makes it easier to hit this case), send messages until mailboxes overflow.

Edit: I'm not sure the error state is actually a part of this or would actually work. I think I'm overflowing just through normal operation.

Relevant log output

Impact

Major – Severely degrades functionality; workaround is difficult or unavailable.

Environment

Commit: 0285cf4
Device: Custom IMXRT1064 board

Additional Context

No response

Metadata

Metadata

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions