Skip to content

Fix correctness bugs: NULL symbol deref, register-buffer overflow, memory-range calculation - #1

Open
HeavenlyDevv wants to merge 1 commit into
ManyCoreResearchTeam:extensionsfrom
HeavenlyDevv:fix/correctness-null-guards-bounds-memrange
Open

Fix correctness bugs: NULL symbol deref, register-buffer overflow, memory-range calculation#1
HeavenlyDevv wants to merge 1 commit into
ManyCoreResearchTeam:extensionsfrom
HeavenlyDevv:fix/correctness-null-guards-bounds-memrange

Conversation

@HeavenlyDevv

Copy link
Copy Markdown

Summary

Three pre-existing correctness bugs in the fault-injection flow. Each is independent of any feature work and can be reviewed/merged on its own. All three compile cleanly (-Werror) against a fresh clone of extensions.


Bug 1 — NULL symbol dereference aborts the simulator

What happens: getSymbolValue() (and the variable-trace paths in serviceHandler) call vmirtGetSymbolAddr/Size(funcSymbol) before checking the symbol for NULL, and the "not found" branch calls vmirtGetSymbolName(funcSymbol) with funcSymbol == NULL. If the traced symbol does not exist (e.g. a mistyped TRACE_VARIABLE), the run aborts:

Internal Abort (VMIRTASRT) .../vmiRt.c:2003:vmirtGetSymbolSize : NULL symbol

Fix: guard every pointer (processor, symbolName, buffer, dataDomain, funcSymbol/varSymbol) and only read memory when the symbol is actually found — looking it up on the processor first, then on its SMP parent. Applied to getSymbolValue() and the five symbol-resolution paths in serviceHandler.

platformOP/intercept/intercept.c


Bug 2 — possibleRegisters[50] buffer overflow

What happens: initialize() copies the active architecture's register list into the global buffer possibleRegisters[50][10]:

for(int i=0; i<numberOfRegistersToCompare; i++)
    strcpy(possibleRegisters[i], possibleRegistersV8[i]);

possibleRegistersV8 has 65 entries (x0..x30, sp, pc, v0..v31, END_LIST) — already more than 50 — so the strcpy writes past the array and corrupts adjacent global memory.

Fix: size the buffer through a named MAX_REGISTERS (80) and clamp the loop count in each of the three copy loops so the write can never run past the array.

platformOP/commonStructsAndEnumerators.h, platformOP/harness/faultInjector.c


Bug 3 — Memory-range calculation (size used as address, .heap doesn't exist)

What happens: the baremetal memory-range block passes --memhighaddress=$FlashSize — the section size — where an end address is expected, and reads RAMEnd from a .heap section that does not exist in typical baremetal binaries (so it comes out empty). A memory campaign then gets an empty or negative range.

Example (.text at 0x10120, size 0x7d4, no .heap):

Mode Before After
default [65824 .. <empty>] (RAMEnd from absent .heap) valid range
FLASH [65824 .. 2004] → span −63820 (size used as address) [65824 .. 67828] span 2004 (= .text size)

Fix: compute FlashEnd = EntryAddress + FlashSize and RAMEnd = RAMDataAddress + RAMBSSSize.

FI.sh


Validation

All three fixes compile cleanly under -Werror in the OVP environment against a fresh extensions checkout. ARM code paths are unaffected — the changes only correct incorrect behavior, they do not alter control flow.

…unds, memory-range calculation

Three pre-existing bugs in the fault-injection flow, fixed independently of
any RISC-V feature work:

1. intercept.c: getSymbolValue() and the serviceHandler variable-trace paths
   dereferenced a NULL symbol (vmirtGetSymbolAddr/Size/Name) when the traced
   symbol did not exist, aborting the simulator. Guard every pointer and only
   read memory when the symbol is found (processor first, SMP-parent fallback).

2. commonStructsAndEnumerators.h + faultInjector.c: possibleRegisters[50] is
   too small for the ARMv8 list (int+SIMD+END = 66 entries) and overflows in
   the strcpy copy loop. Size it via MAX_REGISTERS (80) and clamp the loop
   count so the write can never run past the array.

3. FI.sh: the memory-range block passed FlashSize (a size) as the high address
   and read RAMEnd from a non-existent .heap section. Compute FlashEnd =
   EntryAddress + FlashSize and RAMEnd = RAMDataAddress + RAMBSSSize.

Verified: all three compile cleanly (-Werror) against a fresh clone of the
extensions branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant