Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAN DLC field allows values higher than 8 in standard mode #15361

Closed
Martyx00 opened this issue Jan 2, 2023 · 9 comments · Fixed by #15374
Closed

CAN DLC field allows values higher than 8 in standard mode #15361

Martyx00 opened this issue Jan 2, 2023 · 9 comments · Fixed by #15374

Comments

@Martyx00
Copy link
Contributor

Martyx00 commented Jan 2, 2023

Description of defect

The code responsible for handling incoming CAN messages allows DLC field values higher than 8. This is not in-line with the standard CAN protocol (such values are only used in CAN-FD). This report is created since several issues where developers assumed that the DLC value is maximum of 8 were found. Example of such an issue could be a simple memcpy operation like this:
memcpy(dest_buffer,can_msg.data,can_msg.len)
In such situation sending an arbitrary CAN message with DLC set to maximum value (15) would cause a buffer overflow.

Target(s) affected by this defect ?

Any code using CAN bus from MbedOS.

Toolchain(s) (name and version) displaying this defect ?

CAN interface handler

What version of Mbed-os are you using (tag or sha) ?

All versions of MbedOS up to current (https://github.com/ARMmbed/mbed-os/releases/tag/mbed-os-6.16.0)

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

Not Applicable

How is this defect reproduced ?

Any code working with CAN messages on the receiving end (example below was used in the PoC - see the attached screenshot). The sending side could be any Arduino board with CAN controller.

#include "mbed.h"
CAN can1(PB_8, PB_9);
// main() runs in its own thread in the OS
int main()
{
    CANMessage msg;
    printf("main()\n");
    can1.frequency(500000);
    
    while (true) {
        if (can1.read(msg)) {
            printf("Message received:\n ID: %d\n DLC: %d\n", msg.id,msg.len);
        } 
    }
}

DLC_GT_8

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 3, 2023

Have you looked at where this lentgh is coming from?

Looking at CAN_Message, it's constructor sets length to maximum 8 bits. It is predefined to 8 in its ctor. Thus the example above should have msg.len set to 8. This is however not true if you pass it down to HAL.

In this case, I am checking STM can_api implementation:

msg->len = (uint8_t)0x0F & can->sFIFOMailBox[rxfifo_default].RDTR;

This is where the number > 8 comes from. Can you send a pull request fixing this? It's in can_api.c inside STM HAL, line 1027.

cc @jeromecoutant

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 16, 2023

The fix #15364 fixes the issue for particular implementation. I realized we could add one more check and fix in the upper C++ CAN driver.

This is the current implmentation.

int CAN::read(CANMessage &msg, int handle)
{
    lock();
    int ret = can_read(&_can, &msg, handle);
    unlock();
    return ret;
}

If msg->len is set to above 8, the error is propagated to the user and might cause issues.

What if we add a check for msg.len:

int CAN::read(CANMessage &msg, int handle)
{
    lock();
    int ret = can_read(&_can, &msg, handle);
    if (msg.len > 8) {
        msg.len = 8;
    }
    unlock();
    return ret;
}

Or potentionally we could just error() there if it's above 8bits as it shall not.

The error is better in this case as if anyone really did wrote more than 8 bits, it wrote to a place where it should not in any case. Let's add error() there.

@Martyx00
Copy link
Contributor Author

Fixing in the upper layer seems more reasonable as this will address any similar situation in the HALs with CAN support that might be added in the future. I will cancel the pull request that I did with changes in the STM HAL. Will you update the upper driver?

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 16, 2023

I'll send PR today.

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 16, 2023

I will cancel the pull request that I did with changes in the STM HAL

It's still needed!

@Martyx00
Copy link
Contributor Author

Having second thoughts on the fix in the upper layer, it has to allow CAN FD frames to propage DLC values which can be up to 15, thus the CAN type would have to be checked before throwing error() based on the length.

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 16, 2023

To accomodate anything above 8, the message structure CANmessage would need to be changed:

    unsigned char  data[8];            // Data field
    unsigned char  len;                // Length of data field in bytes

len in this case can be up to 8. I'll cover the current implementation.

0xc0170 added a commit to 0xc0170/mbed-os that referenced this issue Jan 16, 2023
If HAL implementation writes more than 8 bytes of data, error immediately.
CANMessage defines only 8 bytes of data, lenght cannot be > 8.

This fixes ARMmbed#15361

Signed-off-by: Martin Kojtal <[email protected]>
@0xc0170
Copy link
Contributor

0xc0170 commented Jan 16, 2023

I referenced above the fix, please review #15374

0xc0170 added a commit to 0xc0170/mbed-os that referenced this issue Jan 16, 2023
If HAL implementation writes more than 8 bytes of data, error immediately.
CANMessage defines only 8 bytes of data, lenght cannot be > 8.

This fixes ARMmbed#15361

Signed-off-by: Martin Kojtal <[email protected]>
@Martyx00
Copy link
Contributor Author

Closing this issue as it was resolved by mergin the #15373 any subsequent actions related to possible issues when implementing FD CAN support are to be handled separately from this issue.

multiplemonomials pushed a commit to mbed-ce/mbed-os that referenced this issue May 17, 2023
If HAL implementation writes more than 8 bytes of data, error immediately.
CANMessage defines only 8 bytes of data, lenght cannot be > 8.

This fixes ARMmbed#15361

Signed-off-by: Martin Kojtal <[email protected]>
multiplemonomials added a commit to mbed-ce/mbed-os that referenced this issue May 17, 2023
* fix STM32L1 FLASH_SIZE for cat.3 devices with DEV_ID 0x436

* Fix mesh connect semaphore not releasing causing blockage

* Add support of NSAPI_ICMP sockets in Nanostack

* STM32F1: add MCU_STM32F103xD support

* STM32F1: add MCU_STM32F103xG support

* test: Disable failing tests due to echo server

Some tests are failing as echo.mbedcloudtesting.com is not serving TLS
requests anymore.

Signed-off-by: Saheer Babu <[email protected]>

* Check CAN DLC length value

* Fix default interface ID only being used partially

If user sets the default interface ID for a socket (e.g. using setsockopt
with SOCKET_INTERFACE_SELECT), the default interface should take over
other interface selection mechanisms as a interface is bound to the socket.
This applies for both IPv6 local and global scopes for unicast messages
but not for multicast messages as these are bound to a multicast interface
using SOCKET_IPV6_MULTICAST_IF socket option.

* Targets: NXP: IMXRT: Fixed GCC_ARM lds syntax.

Signed-off-by: Yilin Sun <[email protected]>

* CAN: read only up to 8 bytes

If HAL implementation writes more than 8 bytes of data, error immediately.
CANMessage defines only 8 bytes of data, lenght cannot be > 8.

This fixes ARMmbed#15361

Signed-off-by: Martin Kojtal <[email protected]>

* STM32F303xC: add RAM_CCM in GCC linker script

* fix(drivers/emac): Remove incorrect RMII RX ER initialization

* fix(drivers/emac): Add missing SPDX indetifier to ST driver files

* fixed compiler inline issue

* Update Mbed version block

* removed HSE speed limitation for STM32G431RB

* Added HSE range validation for STM32g431xB

* added support for 4, 8 and 16MHz

* M487: Remove unused variable 'u32EscapeFrame'

Remove unused variable 'u32EscapeFrame' in BSP m480_ccap.h to avoid warnings

* force FIFO IRQ for FDCan RX on H7

* Add hardware CRC support to STM32G4

* add support for Nucleo-H745ZI

* Update MAX32670 peripheral drivers with final ones that use by SDK

Signed-off-by: Sadik.Ozer <[email protected]>

* MAX32670 apply mbed required changes on peripheral drivers

Signed-off-by: Sadik.Ozer <[email protected]>

* M467: Support CAN bus

1.  Update BSP CANFD driver
2.  Notes for implementation
    (1) Each CANFD instance supports two IRQ lines. Use only line 0. Line 1 is not used.
    (2) For Rx disabling multiple filter handles,
        1)  Map all filter handles to filter handle 0
        2)  Use Rx FIFO 0 for filter handle 0
    (3) For Rx enabling multiple filter handles,
        1)  Use Rx FIFO 0 for filter handle 0
        2)  Use Rx FIFO 1 for filter handle through first invoking can_filter()
        3)  Use dedicated Rx Buffer for other filter handles
        NOTE: H/W supports mask on Rx FIFO 0/1 but not on dedicated Rx Buffer.
    (4) For Tx, use only dedicated Tx Buffer. BSP CANFD driver doesn't support Tx FIFO/Queue.
    (5) Support no CAN FD.

* Fix 'new[]' array freed with 'delete'

The array _scratch_buf is allocated using new[] in line 761 of
mbed-os/storage/kvstore/securestore/source/SecureStore.cpp.
But it was freed using delete.

* Define default parameters of functions of derived class the same as the base class

The member function bringup() of class ThreadInterface redefines
parameter stack's default value to IPV6_STACK from the inherited default value
DEFAULT_STACK (in Interface).
The default value will be resolved statically, not by dispatch, so this
can cause confusion.
Similar arguments apply to LoWPANNDInterface and WisunInterface.

* Avoid calling virtual functions from constructors and destructors

Virtual functions are resolved statically (not dynamically) in
constructors and destructors for the same class. The call should be made
explicitly static by qualifying it using the scope resolution operator.

* Fix potentially overrunning write of sprintf

Format string "%d" requires 12 bytes (including the null terminator).
Also, use snprintf instead of sprintf to prevent buffer overflow.

* Fix system_clock.c location

Signed-off-by: Jasper Jonker <[email protected]>

* Fix variable name

Signed-off-by: Jasper <[email protected]>

* Change storage-class of secret_buf to static

Storing the address of a local variable (`secret_buf`)
in non-local memory (`prf_ptr->secret`) can cause a
dangling pointer bug if the address is used after the function returns.

* fix compiling errors of FATFileSystem when exFAT was enabled

* Add OSPI support for STM32H7

* Nuvoton: Enable extending sampling time for ADC/EADC

For all Nuvoton targets, enable extending sampling time in ADC/EADC clocks on per-pin basis.

---------

Signed-off-by: Saheer Babu <[email protected]>
Signed-off-by: Yilin Sun <[email protected]>
Signed-off-by: Martin Kojtal <[email protected]>
Signed-off-by: Sadik.Ozer <[email protected]>
Signed-off-by: Jasper Jonker <[email protected]>
Signed-off-by: Jasper <[email protected]>
Co-authored-by: caodd <[email protected]>
Co-authored-by: YannCharbon <[email protected]>
Co-authored-by: Jerome Coutant <[email protected]>
Co-authored-by: Saheer Babu <[email protected]>
Co-authored-by: Martyx00 <[email protected]>
Co-authored-by: Yilin Sun <[email protected]>
Co-authored-by: Martin Kojtal <[email protected]>
Co-authored-by: akiroz <[email protected]>
Co-authored-by: Charles <[email protected]>
Co-authored-by: Leonard Chiang <[email protected]>
Co-authored-by: Chun-Chieh Li <[email protected]>
Co-authored-by: jmcloud <[email protected]>
Co-authored-by: Augusto Zanellato <[email protected]>
Co-authored-by: Sadik.Ozer <[email protected]>
Co-authored-by: Mingjie Shen <[email protected]>
Co-authored-by: Jasper Jonker <[email protected]>
Co-authored-by: wdx04 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants