Description
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:

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