Bug Report: RISC-V Load Access Fault Exception in NuttX Kernel #15177
Labels
Arch: risc-v
Issues related to the RISC-V (32-bit or 64-bit) architecture
Area: Kernel
Kernel issues
OS: Linux
Issues related to Linux (building system, etc)
Type: Bug
Something isn't working
Expected Behavior
The program should execute without any memory access violations or crashes. Specifically, the strnlen function should correctly calculate the length of the string provided as input.
Actual Behavior
Instead of executing normally, the program crashes due to a load access fault when trying to read a byte from what seems to be an invalid or inaccessible memory location.
Description
While running a fuzz test on the NuttX kernel using Syzkaller, an unexpected exception occurred. The system reported a
Load access fault
exception with the following details:• MCAUSE: 0x5 (Indicates a load access fault)
• EPC: 0x80006302 (Program counter at the time of exception)
• MTVAL: 0xffffffffffffffff (Value related to the exception, possibly invalid address)
Querying the nut-img file reveals that the exception happened during the execution of the
strnlen
function, specifically at offset +0x4a from its start 23. The error log indicates that the system was attempting to perform a load byte (lbu
) operation from an address held in registers0
, which appears to be causing the issue.Note: __sanitizer_cov_trace_pc is our instrumentation function.
Debug Logs
The debug logs show that the system was executing various system calls before encountering the exception. Upon reaching the
strnlen
function, it attempted to load a byte from an address stored ins0
. However, this address appears to be invalid or out of bounds, resulting in the load access fault.Before the exception occurs, the system is executing a series of system calls, including but not limited to
syz_sem_getvalue
,syz_mq_close
,syz_vfork
,syz_mq_send
,syz_mq_timedsend
,syz_setenv
, andsyz_timer_gettime
. The last valid call number is #call_num = 18446744073709551615, which is actually the maximum value of an unsigned 64-bit integer, suggesting that there may be an overflow or invalid parameters used.Based on the provided assembly code snippet for
strnlen
, the instruction at0x80006302
is performing albu s3,0(s0)
operation, which attempts to load an unsigned byte into registers3
from the address pointed to bys0
. Given thatMTVAL
contains all ones (0xffffffffffffffff
), it suggests that either the address being accessed does not exist or there is no valid mapping for it in the page tables, leading to the access fault.Steps to Reproduce
To reproduce this issue, one can use Syzkaller to execute system calls against the NuttX kernel. The specific sequence leading up to the crash includes calls such as
syz_sem_getvalue
,syz_mq_close
,syz_vfork
, and others, culminating in the problematic call tostrnlen
.The corresponding syscall specific implementation code is as follows:
Suggested Fix
A potential fix could involve ensuring that all pointers passed to functions like strnlen are properly validated before use. Additionally, implementing checks within the function itself to ensure that it does not attempt to access memory outside of allocated buffers might help prevent similar issues in the future.
The strnlen function is in libs/libc/machine/arch_libc.c with the following code:
The ASan check in the current code assumes that ret is the valid length value returned from strnlen. However, if the incoming string s does not end in \0 or exceeds maxlen, then ret may not accurately reflect the actual string length. In addition, calls to __asan_loadN may cause unnecessary performance overhead or false positives. Therefore, it is recommended that ASan checking be enabled only when it is really needed, and only for memory regions that are known to be valid.
Although strnlen itself is a relatively simple function, care needs to be taken to handle possible boundary cases, such as the null pointer NULL, and while passing in NULL should be considered a programming error in practice, at the kernel level proper error handling can prevent system crashes or other serious consequences.
On which OS does this issue occur?
[OS: Linux]
What is the version of your OS?
Ubuntu 20.04
NuttX Version
2ff2b82
Issue Architecture
[Arch: risc-v]
Issue Area
[Area: Kernel]
Verification
The text was updated successfully, but these errors were encountered: