RT-Thread / RT-Thread/rt-thread

RT-Thread Atomic Operation Deadlock During syz_thread_delay_ms Execution

Open
#9,792 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
12.2k
Forks
5.4k
Avg merge
4d 12h
Merged PRs (30d)
40

Description

RT-Thread Version

2f559906d6202c27142237ab4b1d893034a5b7c3

Hardware Type/Architectures

arm32

Develop Toolchain

GCC

Describe the bug
Expected Behavior:

The rt_hw_atomic_load function should successfully perform an atomic load operation on the specified memory address without causing a system failure or timeout during execution. Specifically, when using the syz_thread_delay_ms function, it is expected that the delay will be executed correctly and the syscall will return normally after the specified time has elapsed.

Actual Behavior:

Upon executing syz_thread_delay_ms, the system experiences an unexpected stop with a qemu run instance merger error due to execution timing out. The VM fails to read registers from the localhost port 33427, indicating a connection refusal. This results in a stack trace pointing towards issues within the atomic_arm.c file at line 84 where rt_hw_atomic_load is called. Additionally, there was an inconsistency between the number of calls made (info.Calls) and the actual number of calls expected (ncalls)

Description:

The issue appears to stem from the implementation of the rt_hw_atomic_load function which attempts to perform an atomic load via LDREX/STREX instructions in a loop until successful. However, under certain conditions, this loop does not terminate properly leading to what seems like a deadlock situation. As a result, the emulator running the RT-Thread kernel times out while trying to execute the test case provided by the fuzzer.

Debug Logs:
#executing syz_thread_delay_ms (0xe760)
2024/09/04 07:22:39 Syscall execution is ok
2024/09/04 07:22:41 VMs=1 candidates=0 corpus=19 coverage=724 exec total=283 (32/min) reproducing=0 
2024/09/04 07:22:49 qemu run inst merger err: execution timed out
2024/09/04 07:22:49 Received stop signal, requires feedback = true
2024/09/04 07:22:49 running diagnose
2024/09/04 07:22:49 VM-0 failed reading regs: dial tcp 127.0.0.1:33427: connect: connection refused
2024/09/04 07:22:49 VM-0 failed reading regs: dial tcp 127.0.0.1:33427: connect: connection refused
2024/09/04 07:22:49 Stack frames at BUG: unexpected stop:
2024/09/04 07:22:49 Level: 1: 1611187668, /root/rtthread/rt-thread/libcpu/arm/common/atomic_arm.c : rt_hw_atomic_load : 84 : 
2024/09/04 07:22:49 Level: 2: 1611454864, /root/rtthread/rt-thread/src/irq.c : rt_interrupt_get_nest : 122 : 
2024/09/04 07:22:49 Level: 3: 1611420692, /root/rtthread/rt-thread/src/clock.c : rt_tick_increase : 88 : 
2024/09/04 07:22:49 Level: 4: 1611236508, /root/rtthread/rt-thread/bsp/qemu-vexpress-a9/drivers/drv_timer.c : rt_hw_timer_isr : 68 : 
2024/09/04 07:22:49 Level: 5: 1611211748, /root/rtthread/rt-thread/libcpu/arm/cortex-a/trap.c : rt_hw_trap_irq : 363 : 
2024/09/04 07:22:49 Level: 6: 1611546348, /root/rtthread/rt-thread/libcpu/arm/cortex-a/start_gcc.S : vector_irq : 385 : 
2024/09/04 07:22:49 Level: 7: 1611231544, /root/rtthread/rt-thread/bsp/qemu-vexpress-a9/drivers/board.c : idle_wfi : 47 : 
2024/09/04 07:22:49 Level: 8: 1611423056, /root/rtthread/rt-thread/src/idle.c : idle_thread_entry : 284 : 
2024/09/04 07:22:49 Level: 9: 1611546932, /root/rtthread/rt-thread/libcpu/arm/cortex-a/start_gcc.S : _thread_start : 628 : 
2024/09/04 07:22:49 [ERROR] Incorrect returned call number: info.Calls : 0 != ncalls : 12 

__Note:kcov.c main.c common_freertos.h executor.h is a file we wrote ourselves.

Steps to Reproduce:
  1. Set up the Rt-Thread environment with the necessary configurations for fuzz testing.
  2. Compile the RT-Thread kernel with debugging symbols enabled.
  3. Use a fuzzer tool such as syzkaller configured to generate random inputs for syscall testing.
  4. Execute the syz_thread_delay_ms function with (0xe760).
#include <rtthread.h>
#include <stdint.h>

// Function for thread delay
long syz_thread_delay_ms(volatile int ms) {
    if (ms <= 0) {
        return -1; // Returns an error, the delay must be positive
    }
    rt_thread_mdelay((rt_int32_t)ms);
    return 0; // Success
}
  1. Observe the behavior; if the bug persists, you should see similar logs indicating a timeout and register access failure.
Other additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with libcpu/arm/common/atomic_arm.c at rt_hw_atomic_load line 84 and trace the stack through src/irq.c, src/clock.c, and bsp/qemu-vexpress-a9/drivers/drv_timer.c. Reproduce the syz_thread_delay_ms(0xe760) case in the qemu-vexpress-a9 setup and compare the timeout and call-count logs. Done means the delay returns normally without the VM timeout or atomic-operation failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
embedded-iot, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.