rt-thread icon indicating copy to clipboard operation
rt-thread copied to clipboard

[Bug] Insufficient pointer validation vulnerability in the sys_select system call in Smart version of RT-Thread

Open x-codingman opened this issue 7 months ago • 2 comments

RT-Thread Version

v5.1.0

Hardware Type/Architectures

Not apply

Develop Toolchain

Other

Describe the bug

Summary

I have identified a vulnerability in the sys_select system call in Smart version of RT-Thread v5.1.0. I am opening this issue for your review, as I could not find a reporting email in the security policy of this repository. This vulnerability stems from insufficient pointer validation, particularly for the timeout parameter. The code only checks if the pointer is NULL but fails to verify whether the pointer points to valid memory. If exploited by a compromised user thread, this issue could lead to severe security consequences, including kernel crashes and potential unauthorized memory access.

Vulnerable Code Location

The vulnerability is present in the rt-thread/components/lwp/lwp_syscall.c file. The issue arises from the lack of proper validation of the timeout parameter pointer. The call graph of this vulnerability is as follows:

  1. rt-thread/components/lwp/lwp_syscall.c:sys_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
  2. rt-thread/components/libc/posix/io/poll/select.cint select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
sysret_t sys_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
#ifdef ARCH_MM_MMU
    int ret = -1;
    fd_set *kreadfds = RT_NULL, *kwritefds = RT_NULL, *kexceptfds = RT_NULL;

    //Omitted code

    ret = select(nfds, kreadfds, kwritefds, kexceptfds, timeout);
    // Omitted code
    return (ret < 0 ? GET_ERRNO() : ret);
#endif
}

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
    int fd;
    int npfds;
    int msec;
    int ndx;
    int ret;
    struct pollfd *pollset = RT_NULL;

    // Omitted code

    /* Convert the timeout to milliseconds */
    if (timeout)
    {
        msec = (int)timeout->tv_sec * 1000 + (int)timeout->tv_usec / 1000; // Vulnerability: Only checks if timeout is NULL, but doesn't verify if it points to valid memory
    }
    else
    {
        msec = -1;
    }

    // Omitted code

    return ret;
}

Vulnerability Description

  1. The vulnerability exists in the select function's handling of the timeout parameter. The code only performs a NULL check on the timeout pointer but fails to verify whether the pointer points to valid memory. This oversight can lead to a memory fault when dereferencing an invalid pointer. The issue is particularly critical because:
    1. The timeout parameter is passed directly from user space to kernel space
    2. The code only checks if the pointer is NULL (if (timeout))
    3. No validation is performed to ensure the pointer points to valid memory before dereferencing it
    4. When accessing timeout->tv_sec and timeout->tv_usec, a memory fault will occur if the pointer points to invalid memory

Impact

This vulnerability has severe security implications:

  1. Kernel Crash: The most immediate impact is a potential kernel crash due to invalid memory access, leading to a Denial of Service (DoS) condition.

  2. Privilege Escalation: In certain scenarios, this vulnerability could potentially be exploited to access kernel memory, leading to privilege escalation.

Other additional context

No response

x-codingman avatar May 20 '25 05:05 x-codingman

The timeout parameter should be checked to check if it can be accessed correctly in kernel mode and used temporarily in kernel memory.

BernardXiong avatar May 20 '25 15:05 BernardXiong

Thank you for your feedback. I have identified and reported several similar issues across different system calls for your review and consideration.

x-codingman avatar May 22 '25 23:05 x-codingman