Skip to content

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

@0xdea

Description

@0xdea

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.

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