Skip to content

[Bug] FinSH console command lacks asynchronous-safe attribute validation #11336

@Acen28

Description

@Acen28

RT-Thread Version

v5.3.0/git-hash: cda0a63

Hardware Type/Architectures

bsp/stm32/stm32f407-atk-explorer

Develop Toolchain

GCC

Describe the bug

Description

In the RT-Thread FinSH component, the console command allows users to dynamically switch the system's log output device at runtime. However, the command's handling logic (and the underlying rt_console_set_device API) only checks if the target device exists, completely failing to validate whether the target device possesses asynchronous-safe attributes or supports interrupt context output (e.g., RT_DEVICE_FLAG_INT_TX).

rt_kprintf is a core logging interface in the RTOS, frequently used within hardware Interrupt Service Routines (ISRs) and low-level kernel assertions. If an attacker or an unaware user redirects the console to a blocking peripheral that internally uses rt_mutex (e.g., I2C, SPI, or certain virtual network devices) via the console command, the system state is "poisoned" (State Poisoning / Type Confusion).

In this state, any subsequent rt_kprintf called from within an ISR (such as a Warning triggered by a peripheral buffer overflow) will trigger the kernel IPC's interrupt safety check assertion. This assertion attempts to print another error using rt_kprintf, causing an infinite recursion and severe memory corruption (Stack Clash), which leads to an instant HardFault (DoS).

Prerequisites to Reproduce

  1. The FinSH component and the console command are enabled.
  2. A registered device with blocking lock logic (e.g., a device named i2c1 or spi1) exists in the system.

Steps to Reproduce

  1. Boot the RT-Thread system and enter the FinSH interactive shell.
  2. Execute the console redirection command, targeting any slow, blocking device:
    msh > console i2c1
  3. The system state is now poisoned. Next, trigger any code path that calls rt_kprintf or LOG_W from within an ISR (for example, flood the UART with garbage data at a high baud rate to trigger a UART RX Buffer Overflow warning).
  4. rt_kprintf routes the warning to the I2C device, and the I2C driver attempts to acquire an rt_mutex inside the ISR.
  5. The kernel IPC check (RT_DEBUG_SCHEDULER_AVAILABLE) detects the interrupt context violation and calls rt_kprintf to report the error.
  6. This forms an infinite recursive deadlock between rt_kprintf and _rt_mutex_take, instantly exhausting stack memory and crashing the device.

Root Cause Analysis (Code Level)

There is a typical device type and attribute validation missing in the source code handling the console command and rt_console_set_device().

The current implementation merely confirms the device exists via rt_device_find(name) and directly switches the pointer:

/* Abstract of the current vulnerable logic */
rt_device_t dev = rt_device_find(name);
if (dev != RT_NULL)
{
    rt_console_set_device(name); // Blind switch, no attribute validation
}

### Other additional context

_No response_

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions