Loading
Commits on Source 11
-
cznic authored
-
cznic authored
This is a classic case of **"Valid C Optimization vs. Strict Memory Safety."** 1. **The Musl C Source:** It is **correct** (by C standards of the time). Musl uses a common optimization: reading 8 bytes (a size\_t) at a time to check for null terminators in parallel. This relies on the assumption that reading aligned words is safe on the hardware level (it won't cross a page boundary and fault). It assumes "dirty reads" of the bytes immediately following the string are harmless. 2. **The Transpiler:** It is **correct**. It faithfully translated the bit-twiddling logic from C to Go. The Problem: AddressSanitizer (ASan) is designed to flag exactly this kind of behavior. * **In standard C:** Reading bytes 12-15 of an 11-byte array usually just reads the next global variable or padding. No harm done. * **With ASan:** ASan inserts "Redzones" (poisoned memory) immediately after every allocation. * **The Conflict:** The Xstrlen function aligns the pointer and then reads a full 8-byte word. For an 11-byte string, the second read grabs bytes 8–15. Bytes 11–15 fall into the ASan redzone, triggering the global-buffer-overflow. The fault lies in this loop strategy: 1. **Alignment:** The code advances s until it is 8-byte aligned. 2. **Word Read:** It casts the pointer to \*uint64 and reads. 3. **The Overshoot:** If you have an 11-byte string aligned at address 0x1000: * **First read (0x1000):** Reads bytes 0-7. (Safe) * **Second read (0x1008):** Reads bytes 8-15. (Safe for bytes 8-10, **Illegal** for 11-15). Musl doesn't care because it masks out the garbage bytes later using the HASZERO logic. ASan cares because you *touched* the poisoned memory.
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored
-
cznic authored