RT-Thread / RT-Thread/rt-thread
[Bug] Multiple Bug Report When Running the System
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
2f55990
Hardware Type/Architectures
QEMU/arm32
Develop Toolchain
GCC
Describe the bug
Hi, when I test the RTthread with our fuzzing tool, we encounter several crashes in kernel.
Step to reproduce
To reproduce, modify the rtthread/rt-thread/bsp/qemu-vexpress-a9.
run scons . and run with qemu-nographic.sh for each crash at a time can observe the crash.
The following are the reproducer program
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <rtthread.h>
long syz_event_recv(volatile int event, volatile int set, volatile int option, volatile int timeout, volatile int recved) {
rt_uint32_t recv;
rt_err_t result = rt_event_recv((rt_event_t)event, (rt_uint32_t)set, (rt_uint8_t)option, (rt_int32_t)timeout, &recv);
if (result != RT_EOK) {
//rt_kprintf("Failed to receive event: %d\n", result);
return -1;
}
*(rt_uint32_t *)recved = recv;
return 0;
}
void syz_traverse_object_list() {
rt_object_t obj = RT_NULL;
rt_list_t *node = RT_NULL;
//rt_kprintf("Traversing object list:\n");
rt_list_for_each(node, &(obj_info.object_list)) {
obj = rt_list_entry(node, struct rt_object, list);
//rt_kprintf("Object name: %s\n", obj->name);
}
}
long syz_mp_complex_usage(volatile int mp_handle) {
// Attempt to allocate multiple blocks
void *blocks[10];
for (int i = 0; i < 10; i++) {
blocks[i] = rt_mp_alloc((rt_mp_t)mp_handle, RT_WAITING_NO);
if (blocks[i] == RT_NULL) {
//rt_kprintf("Failed to allocate block at index %d.\n", i);
// Attempt to free all allocated blocks so far
for (int j = 0; j < i; j++) {
rt_mp_free(blocks[j]);
}
return -1; // Failure
}
}
for (int i = 0; i < 10; i++) {
rt_mp_free(blocks[i]);
}
return 0; // Success
}
void syz_object_init_update_info() {
rt_object_init(&obj_example, RT_Object_Class_Thread, "et");
obj_info.type = RT_Object_Class_Thread;
rt_list_insert_after(&(obj_info.object_list), &(obj_example.list));
obj_info.object_size = sizeof(obj_example);
}
void syz_system_heap_init() {
void *begin_addr = malloc(1024 * 1024);
void *end_addr = begin_addr + 1024 * 1024;
rt_system_heap_init(begin_addr, end_addr);
}
long syz_event_send(volatile int event, volatile int set) {
rt_err_t result = rt_event_send((rt_event_t)event, (rt_uint32_t)set);
if (result != RT_EOK) {
//rt_kprintf("Failed to send event: %d\n", result);
return -1;
}
return 0;
}
int main(void)
{
executor_check_ints();
rt_kprintf("Hello RT-Thread!\n");
rt_kprintf("Starting executor.\n");
// crash 1
syz_event_recv (0x4, 0x0, 0x2, 0x0, 0xa000);
// crash 2
syz_traverse_object_list();
// crash 3
syz_mp_complex_usage (0xc4);
// crash 4
syz_object_init_update_info();
// crash 5
syz_system_heap_init();
// crash 6
syz_event_send (0x7fff, 0x0);
rt_kprintf("Finish executor.\n");
return 0;
}
System Logs:
crash 1:
it end up in
rt_uint8_t rt_object_get_type(rt_object_t object)
{
/* object check */
RT_ASSERT(object != RT_NULL);
return object->type & ~RT_Object_Class_Static;
}
where failed to check the validity of object->type & ~RT_Object_Class_Static; cause the crash.
crash 2:
It ends up in
rt_inline int rt_list_isempty(const rt_list_t *l)
{
return l->next == l;
}
My guess is there might be a illegal memory access in return l->next == l;, but I failed to analyze the actual case here.
crash 3:
The program crashed at thread = rt_thread_self();, but I failed to debug deeper, as it directly crashed at rt_thread_self.
void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time)
{
rt_uint8_t *block_ptr;
rt_base_t level;
struct rt_thread *thread;
rt_uint32_t before_sleep = 0;
/* parameter check */
RT_ASSERT(mp != RT_NULL);
/* get current thread */
thread = rt_thread_self();
crash 4:
The program crashed at type = (enum rt_object_class_type)(type & ~RT_Object_Class_Static);, similar to crash 1, where it seems to fail to check the vadaility of a certain value and trigger this error.
struct rt_object_information *
rt_object_get_information(enum rt_object_class_type type)
{
int index;
type = (enum rt_object_class_type)(type & ~RT_Object_Class_Static);
for (index = 0; index < RT_Object_Info_Unknown; index ++)
if (_object_container[index].type == type) return &_object_container[index];
return RT_NULL;
}
crash 5:
It ends up in _heap_lock, where seems rt_spin_lock_irqsave triggers an illegal memory access.
rt_inline rt_base_t _heap_lock(void)
{
#if defined(RT_USING_HEAP_ISR)
return rt_spin_lock_irqsave(&_heap_spinlock);
#elif defined(RT_USING_MUTEX)
if (rt_thread_self())
return rt_mutex_take(&_lock, RT_WAITING_FOREVER);
crash 6:
It crashed at rt_event_send, where seems failed to check the validity of event.
long syz_event_send(volatile int event, volatile int set) {
rt_err_t result = rt_event_send((rt_event_t)event, (rt_uint32_t)set);
if (result != RT_EOK) {
//rt_kprintf("Failed to send event: %d\n", result);
return -1;
}
return 0;
}
It would be so nice of you to review this bug report. Thank you again for taking the time. Any suggestions or feedback you can provide would be very helpful.
Best regards,
Other additional context
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in bsp/qemu-vexpress-a9, build with scons ., and run qemu-nographic.sh separately for each reproducer. Trace the listed entry points, including rt_event_recv, rt_list_isempty, rt_mp_alloc, rt_object_get_information, _heap_lock, and rt_event_send, then determine which crashes are reproducible kernel defects versus invalid inputs. Done means each reported crash has a documented disposition and confirmed regression coverage where applicable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- embedded-iot, operating-systems, testing-qa
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100