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.52k stars 5.03k forks source link

Multiple vulnerabilities in RT-Thread ymodem utility #8291

Open 0xdea opened 11 months ago

0xdea commented 11 months ago

Hi,

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

Multiple potential vulnerabilities in RT-Thread ymodem utility

Summary

I spotted some potential vulnerabilities at the following locations in the RT-Thread ymodem utility source code: https://github.com/RT-Thread/rt-thread/blob/master/components/utilities/ymodem/ry_sy.c#L149 https://github.com/RT-Thread/rt-thread/blob/master/components/utilities/ymodem/ry_sy.c#L205 https://github.com/RT-Thread/rt-thread/blob/master/components/utilities/ymodem/ry_sy.c#L225

Details

Unbounded rt_sprintf() in the _rym_send_begin() function could lead to a buffer overflow at the marked line:

static enum rym_code _rym_send_begin(
    struct rym_ctx *ctx,
    rt_uint8_t *buf,
    rt_size_t len)
{
    struct custom_ctx *cctx = (struct custom_ctx *)ctx;
    struct stat file_buf;
    char insert_0 = '\0';
    rt_err_t err;

    cctx->fd = open(cctx->fpath, O_RDONLY);
    if (cctx->fd < 0)
    {
        err = rt_get_errno();
        rt_kprintf("error open file: %d\n", err);
        return RYM_ERR_FILE;
    }
    rt_memset(buf, 0, len);
    err = stat(cctx->fpath, &file_buf);
    if (err != RT_EOK)
    {
        rt_kprintf("error open file.\n");
        return RYM_ERR_FILE;
    }

    const char *fdst = _get_path_lastname(cctx->fpath);
    if(fdst != cctx->fpath)
    {
        fdst = dfs_normalize_path(RT_NULL, fdst);
        if (fdst == RT_NULL)
        {
            return RYM_ERR_FILE;
        }
    }

    rt_sprintf((char *)buf, "%s%c%d", fdst, insert_0, file_buf.st_size); /* VULN: if we can make fdst large enough, there's no bound checking */

    return RYM_CODE_SOH;
}

Lack of NUL-termination in the rym_download_file() function at the marked line:

static rt_err_t rym_download_file(rt_device_t idev,const char *file_path)
{
    rt_err_t res;
    struct custom_ctx *ctx = rt_calloc(1, sizeof(*ctx));

    if (!ctx)
    {
        rt_kprintf("rt_malloc failed\n");
        return -RT_ENOMEM;
    }
    ctx->fd = -1;
    rt_strncpy(ctx->fpath, file_path, DFS_PATH_MAX); /* VULN: unterm if file_path is at least DFS_PATH_MAX bytes (comes from argv); it might cause infoleak or memory corruption */
    RT_ASSERT(idev);
    res = rym_recv_on_device(&ctx->parent, idev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
                             _rym_recv_begin, _rym_recv_data, _rym_recv_end, 1000);
    rt_free(ctx);

    return res;
}

Lack of NUL-termination in the rym_upload_file() function at the marked line:

static rt_err_t rym_upload_file(rt_device_t idev, const char *file_path)
{
    rt_err_t res = 0;

    struct custom_ctx *ctx = rt_calloc(1, sizeof(*ctx));
    if (!ctx)
    {
        rt_kprintf("rt_malloc failed\n");
        return -RT_ENOMEM;
    }
    ctx->fd = -1;
    rt_strncpy(ctx->fpath, file_path, DFS_PATH_MAX); /* VULN: unterm if file_path is at least DFS_PATH_MAX bytes (comes from argv); it might cause infoleak or memory corruption */
    RT_ASSERT(idev);
    res = rym_send_on_device(&ctx->parent, idev,
                             RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
                             _rym_send_begin, _rym_send_data, _rym_send_end, 1000);
    rt_free(ctx);

    return res;
}

Impact

If the unchecked input above is confirmed to be attacker-controlled and crossing a security boundary, the impact of the reported vulnerabilities could range from information leakage to denial of service, or even arbitrary code execution.

0xdea commented 10 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 9 months ago

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