Zepp-Hanzj opened a new pull request, #19581:
URL: https://github.com/apache/nuttx/pull/19581

   ## Summary
   
   - restore correct sign-bit testing when decoding signed inline UBSan values
   - keep the unsigned-to-signed conversion explicit
   - avoid shifting `1llu` by 64 when constructing a full-width mask
   
   ## Root cause
   
   The sign-bit expression currently lacks parentheses:
   
   ```c
   ret & (1llu << (bits - 1)) != 0
   ```
   
   Because `!=` has higher precedence than bitwise AND, this is evaluated as:
   
   ```c
   ret & ((1llu << (bits - 1)) != 0)
   ```
   
   The decoder therefore tests bit zero instead of the sign bit.  For example,
   an inline signed 32-bit value of `1` is decoded as `-4294967295`, while the
   negative even value `-2` is decoded as a large positive value.
   
   The mask expression also evaluates `1llu << 64` for a 64-bit inline value.
   That shift is undefined behavior and can recursively invoke UBSan while the
   runtime is handling the original report.
   
   Use a right shift of `UINT64_MAX` to construct masks for all supported 
widths,
   and restore the explicit signed conversion and sign-bit parentheses that were
   lost in commit 9ff99c6d0fc5445e9c668687d5da0cce211d235a.
   
   ## Validation
   
   ### STM32F407ZG hardware
   
   Environment:
   
   - custom STM32F407ZG-P1 board, STM32F407ZG Cortex-M4
   - SEGGER J-Link over SWD
   - `arm-none-eabi-gcc 9.2.1`
   - `CONFIG_MM_UBSAN=y`
   - `CONFIG_MM_UBSAN_ALL` disabled
   - `CONFIG_MM_UBSAN_TRAP_ON_ERROR` disabled
   - the reproduction application compiled with `-fsanitize=undefined`
   
   The test performs signed left shifts with `lhs = -2` and `rhs = 1` for both
   32-bit and 64-bit operands.
   
   Before:
   
   ```text
   UBSAN: shift-out-of-bounds in ostest_main.c:720:20
   shift exponent -4294967295 is negative
   UBSAN: shift-out-of-bounds in ostest_main.c:724:20
   left shift of negative value -2
   ```
   
   After:
   
   ```text
   UBSAN: shift-out-of-bounds in ostest_main.c:720:20
   left shift of negative value -2
   UBSAN: shift-out-of-bounds in ostest_main.c:724:20
   left shift of negative value -2
   ```
   
   ### x86_64 simulator
   
   Built `sim:ostest` with:
   
   ```text
   CONFIG_MM_UBSAN=y
   CONFIG_MM_UBSAN_ALL=y
   CONFIG_MM_UBSAN_TRAP_ON_ERROR=n
   ```
   
   Before the change, the 32-bit operand was decoded incorrectly and the 64-bit
   case recursively reported a shift-by-64 error from `ubsan.c`.  After the
   change, both cases report `left shift of negative value -2`, with no 
recursive
   runtime report.
   
   Additional checks:
   
   - latest `upstream/master` build and run
   - `nxstyle mm/ubsan/ubsan.c`
   - `git diff --check`
   - exhaustive decoder checks for 1/2/4/8/16-bit values
   - 32/64-bit boundary-value checks at `-O0` and `-O2`
   - strict host build with `-Wall -Wextra -Wconversion -Wsign-conversion 
-Werror`
   - Cortex-M4 disassembly comparison confirming the explicit cast does not
     change the instructions exercised by the hardware test
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to