RT-Thread / rt-thread

RT-Thread is an open source IoT Real-Time Operating System (RTOS).
https://www.rt-thread.io
Apache License 2.0
10.38k stars 4.99k forks source link

Out-of-bounds static array access in RT-Thread var_export utility #8290

Open 0xdea opened 10 months ago

0xdea commented 10 months ago

Hi,

I would like to report another potential vulnerability in the current version of RT-Thread. Please let me know if you plan to ask for a CVE ID in case the vulnerability is confirmed. I'm available if you need further clarifications.

Potential out-of-bounds static array access in RT-Thread var_export utility

Summary

I spotted a potential out-of-bounds static array access at the following location in the RT-Thread var_export utility source code: https://github.com/RT-Thread/rt-thread/blob/master/components/utilities/var_export/var_export.c#L97-L122

Details

Improper size check due to the use of RT_ASSERT() in the var_export_init() function at the marked line, which if compiled out in production code could lead to multiple out-of-bounds ve_exporter_tab static array accesses in the next lines:

int var_export_init(void)
{
    /* initialize the var export table.*/
#if defined(__ARMCC_VERSION)                        /* for ARM C Compiler */
    ve_exporter_table = &__ve_table_start + 1;
    ve_exporter_num = &__ve_table_end - &__ve_table_start;
#elif defined (__IAR_SYSTEMS_ICC__)                 /* for IAR Compiler */
    ve_exporter_table = &__ve_table_start + 1;
    ve_exporter_num = &__ve_table_end - &__ve_table_start - 1;
#elif defined (__GNUC__)                            /* for GCC Compiler */
    extern const int __ve_table_start;
    extern const int __ve_table_end;
    ve_exporter_table = (const ve_exporter_t *)&__ve_table_start;
    ve_exporter_num = (const ve_exporter_t *)&__ve_table_end - ve_exporter_table;
#elif defined (_MSC_VER)                            /* for MS VC++ compiler */
    unsigned int *ptr_begin = (unsigned int *)&__ve_table_start;
    unsigned int *ptr_end = (unsigned int *)&__ve_table_end;
    static ve_exporter_t ve_exporter_tab[2048];
    static char __vexp_strbuf1[1024];
    static char __vexp_strbuf2[1024];
    ve_exporter_t ve_exporter_temp;
    rt_size_t index_i, index_j;

    /* past the three members in first ptr_begin */
    ptr_begin += (sizeof(struct ve_exporter) / sizeof(unsigned int));
    while (*ptr_begin == 0) ptr_begin++;
    do ptr_end--; while (*ptr_end == 0);

    /* Find var objects in custom segments to solve the problem of holes in objects in different files */
    ve_exporter_num = ve_init_find_obj(ptr_begin, ptr_end, ve_exporter_tab);

    /* check if the ve_exporter_num is out of bounds */
    RT_ASSERT(ve_exporter_num < (sizeof(ve_exporter_tab) / sizeof(ve_exporter_t))); /* VULN: size check is implemented via assertion */

    /* bubble sort algorithms */
    for (index_i = 0; index_i < (ve_exporter_num - 1); index_i++)
    {
        for (index_j = 0; index_j < ((ve_exporter_num - 1) - index_i); index_j++)
        {
            /* splice ve_exporter's module and ve_exporter's identifier into a complete string */
            rt_snprintf(__vexp_strbuf1,
                        sizeof(__vexp_strbuf1),
                        "%s%s",
                        ve_exporter_tab[index_j].module,
                        ve_exporter_tab[index_j].identifier);
            rt_snprintf(__vexp_strbuf2,
                        sizeof(__vexp_strbuf2),
                        "%s%s",
                        ve_exporter_tab[index_j + 1].module,
                        ve_exporter_tab[index_j + 1].identifier);
            if (rt_strcmp(__vexp_strbuf1, __vexp_strbuf2) > 0)
            {
                ve_exporter_temp = ve_exporter_tab[index_j];
                ve_exporter_tab[index_j] = ve_exporter_tab[index_j + 1];
                ve_exporter_tab[index_j + 1] = ve_exporter_temp;
            }
        }
    }

    ve_exporter_table = ve_exporter_tab;
#endif /* __ARMCC_VERSION */

    return ve_exporter_num;
}

Impact

If the unchecked input above is confirmed to be attacker-controlled and crossing a security boundary, the impact of the reported buffer overflow vulnerability could range from denial of service to arbitrary code execution.

0xdea commented 9 months ago

Hi, it's been one month since I reported this vulnerability, and I wanted to ask if you have any update. As standard practice, I plan to request a CVE ID for every confirmed vulnerability. I also intend to publish an advisory by February at the latest, unless there's a specific reason to postpone. Thanks!

0xdea commented 8 months ago

Hi there, CVE-2024-25392 was assigned to this vulnerability. I'm planning to publish my security advisory and writeup on March 5th. Thanks.