uBPF Validation Plan

Document Version: 1.2.0 Date: 2026-06-12 Status: Draft — Refreshed from current test inventory


1. Overview

1.1 Objectives

This validation plan defines how the uBPF virtual machine library is verified against its requirements specification (docs/specs/requirements.md). It maps existing tests to requirements, identifies coverage gaps, and provides a framework for ongoing validation.

1.2 System Under Test

The uBPF library including:

  • Core VM interpreter (vm/ubpf_vm.c)
  • JIT compilers (vm/ubpf_jit_x86_64.c, vm/ubpf_jit_arm64.c)
  • ELF loader (vm/ubpf_loader.c)
  • Instruction validator (vm/ubpf_instruction_valid.c)
  • Public API (vm/inc/ubpf.h)
  • Python assembler/disassembler (ubpf/)

1.3 Validation Approach

uBPF uses a multi-layered testing strategy:

  1. Data-driven tests.data files parsed by Python test framework
  2. Custom C++ tests — targeted scenarios for specific features
  3. Conformance suite — BPF ISA standard compliance (313 tests)
  4. Differential fuzzing — interpreter vs. JIT comparison with PREVAIL verifier
  5. Static analysis — CodeQL, scan-build, cpplint, pylint
  6. Dynamic analysis — ASan, UBSan, Valgrind

2. Scope of Validation

2.1 In Scope

  • All public API functions in ubpf.h
  • Interpreter execution correctness
  • JIT compilation correctness (x86-64, ARM64)
  • ELF loading and relocation processing
  • Instruction validation and error handling
  • Security feature effectiveness
  • Platform-specific behavior (Windows, Linux, macOS)
  • Python assembler/disassembler correctness

2.2 Out of Scope

  • Performance benchmarking (no perf regression tests exist)
  • Thread safety / concurrency testing
  • Formal verification of JIT output
  • External verifier (PREVAIL) correctness
  • Stress testing (large programs, deep recursion)

2.3 Constraints

  • ARM64 JIT tests require QEMU on x86-64 hosts or native ARM64 hardware
  • Fuzzing requires Clang (libFuzzer integration)
  • Some tests require environment variables (e.g., UBPF_ENABLE_CONSTANT_BLINDING=1)
  • Valgrind only available on Linux

3. Test Strategy

3.1 Test Levels

LevelDescriptionToolsCoverage
UnitIndividual instruction execution.data files + test_vm.pyISA compliance
IntegrationVM lifecycle + loading + executionCustom C++ testsAPI interactions
SystemFull pipeline (load ELF → compile → execute)test_elf.py, ubpf_pluginEnd-to-end
RegressionPrevent reintroduction of fixed bugsFull CTest suiteAll areas
FuzzingFind edge cases and differential bugslibFuzzer + PREVAILInterpreter/JIT parity

3.2 Test Techniques

TechniqueApplication
Equivalence partitioningALU operations by operand type (reg/imm, 32/64-bit)
Boundary value analysisRegister ranges (0, 9, 10), instruction count limits, stack boundaries
Error guessingDivision by zero, stack overflow, invalid opcodes
Differential testingInterpreter vs. JIT output comparison (fuzzer)
Mutation testingRegister offset variations (20 per test in JIT)
Conformance testingBPF ISA standard (RFC 9669) compliance

3.3 Test Infrastructure

Python Framework (test_framework/):

  • testdata.py — Parses .data files into test parameters
  • test_vm.py — Interpreter execution (1 test per .data file)
  • test_jit.py — JIT compilation (20 register-offset variants per .data file)
  • test_elf.py — ELF format loading
  • test_assembler.py — Assembly → binary verification
  • test_disassembler.py — Binary → assembly verification
  • test_roundtrip.py — Assembler → binary → disassembler consistency

Custom Tests (custom_tests/):

  • 17 C++20 test programs with markdown descriptors
  • Each returns 0 (pass) or non-zero (fail)
  • Some read input from stdin via .input data files

Conformance Suite (external/bpf_conformance/):

  • 313 .data files for standard eBPF instruction semantics
  • Executed via ubpf_plugin for both interpreter and JIT
  • The uBPF CTest wiring also routes the repository's 104 local .data files through the same plugin contract

Fuzzer (libfuzzer/libfuzz_harness.cc):

  • Differential testing: interpreter vs. JIT
  • Optional PREVAIL verifier integration
  • Configurable via environment variables

4. Requirements Traceability Matrix

4.1 VM Lifecycle

REQ-IDRequirementTest CasesCoverage
REQ-LIFE-001VM creationTC-LIFE-001High — implicitly tested by all tests
REQ-LIFE-002VM default stateTC-LIFE-004Medium — tested indirectly via default behavior
REQ-LIFE-003VM creation — allocationsTC-LIFE-006Low[GAP: no explicit OOM tests]
REQ-LIFE-004Platform JIT selectionTC-LIFE-005High — CI runs on x86-64, ARM64, macOS
REQ-LIFE-005VM destructionTC-LIFE-002Medium — Valgrind checks, reload_code_memleak
REQ-LIFE-006Code unloadingTC-LIFE-003High — unload_reload.data, reload.data

4.2 Program Loading

REQ-IDRequirementTest CasesCoverage
REQ-LOAD-001Code length validationTC-LOAD-002Medium[GAP: no test for non-multiple-of-8]
REQ-LOAD-002Maximum instruction countTC-LOAD-003Low[GAP: no test with 65536+ instructions]
REQ-LOAD-003Double-load preventionTC-LOAD-001High — all .data tests call ubpf_load
REQ-LOAD-004Instruction validationTC-LOAD-004High — tests/errors/*, atomic_validate custom test
REQ-LOAD-005Read-only bytecode storageTC-LOAD-007, TC-LOAD-008Medium — readonly_bytecode custom test (toggles mode only; [GAP: no direct test that bytecode pages are read-only when enabled])
REQ-LOAD-006Pointer secret encodingTC-LOAD-009Medium[GAP: no direct test of pointer secret encoding correctness]
REQ-LOAD-007Local function markingTC-LOAD-010High — call_local_use_stack.data, factorial.data
REQ-LOAD-008Stack alignment validationTC-LOAD-005High — custom_local_function_stack_size tests
REQ-LOAD-009Sub-program containmentTC-LOAD-006Medium — tested via local call tests
REQ-LOAD-010Jump target validationTC-LOAD-004High — tested via instruction validation
REQ-LOAD-011LDDW pairing validationTC-LOAD-004High — tested via instruction validation

4.3 Program Execution

REQ-IDRequirementTest CasesCoverage
REQ-EXEC-001Interpreter entry pointTC-EXEC-001High — test_vm.py runs all .data files
REQ-EXEC-002Extended interpreter entry pointTC-EXEC-002Medium[GAP: limited direct exec_ex tests]
REQ-EXEC-003Register initializationTC-EXEC-003High — mem/result comparison in all tests
REQ-EXEC-004Code-not-loaded guardTC-EXEC-004Medium[GAP: no explicit test for exec without load]
REQ-EXEC-005Instruction limit enforcementTC-EXEC-009Low[GAP: no direct instruction limit test]
REQ-EXEC-006Call depth limitTC-EXEC-007High — factorial.data, call_local_use_stack.data, stack tests
REQ-EXEC-007XOR-decoded instruction fetchTC-EXEC-004High — 360+ .data tests + fuzzer (implicit)
REQ-EXEC-008Unwind function supportTC-EXEC-008Medium — call_unwind.data
REQ-EXEC-009Debug callback invocationTC-EXEC-010High — debug_function custom test

4.4 JIT Compilation

REQ-IDRequirementTest CasesCoverage
REQ-JIT-001compile APITC-JIT-001High — test_jit.py runs all .data files through JIT
REQ-JIT-002compile_ex API (BasicJitMode & ExtendedJitMode)TC-JIT-002, TC-JIT-003, TC-JIT-004High — BasicJitMode is the default in test_jit.py; ExtendedJitMode tested via ubpf_plugin with --jit
REQ-JIT-003Code cachingTC-JIT-005Low[GAP: no explicit caching test]
REQ-JIT-004Executable memory (W⊕X)TC-JIT-006Medium — implicitly tested; ASan would catch violations
REQ-JIT-005JIT buffer sizingTC-JIT-011High — jit_buffer_too_small custom test
REQ-JIT-006copy_jit APITC-JIT-008Medium — indirectly exercised by ubpf_plugin; [GAP: no dedicated API-focused unit test]
REQ-JIT-007translate APITC-JIT-007Low[GAP: no direct translate API test]
REQ-JIT-008Instruction limit non-applicabilityTC-JIT-012Low[GAP: no test verifying JIT ignores instruction limit]
REQ-JIT-009x86-64 calling conventionsTC-JIT-009High — CI tests on Windows + Linux (different ABIs)
REQ-JIT-010ARM64 backend supportTC-JIT-010High — CI tests on ARM64 (native + QEMU)
REQ-JIT-011Post-compilation helper updateTC-JIT-013High — update_helpers, update_dispatcher custom tests

4.5 ELF Loading

REQ-IDRequirementTest CasesCoverage
REQ-ELF-001ELF header validationTC-ELF-002Medium[GAP: no tests with malformed ELF headers]
REQ-ELF-002Section count limitTC-ELF-008Low[GAP: no test with >32 sections]
REQ-ELF-003ELF bounds checkingTC-ELF-003High — tests/elf/ directory
REQ-ELF-004R_BPF_64_64 data relocationTC-ELF-004High — bpf/rel_64_32.bpf.c, tests/elf/
REQ-ELF-005R_BPF_64_32 helper relocationTC-ELF-005High — conformance suite helper tests
REQ-ELF-006ELF wrapper functions (load_elf)TC-ELF-001High — test_elf.py
REQ-ELF-007Multi-function ELF linkingTC-ELF-006, TC-ELF-007Medium — tested via multi-function ELF programs; [GAP: no explicit named-main test]

4.6 Instruction Set

REQ-IDRequirementTest CasesCoverage
REQ-ISA-001Instruction format (8 bytes)TC-ISA-001High — assembler/raw comparison in all .data tests
REQ-ISA-002Register model (r0-r10)TC-ISA-002High — frame_pointer custom test, JIT register offset variants
REQ-ISA-003ALU operations (32-bit and 64-bit)TC-ISA-003, TC-ISA-004High — alu.data, alu64.data, 100+ conformance tests
REQ-ISA-004Signed division and moduloTC-ISA-013High — sdiv32.data, sdiv64.data, smod32.data, smod64.data
REQ-ISA-005MOV with sign-extension (MOVSX)TC-ISA-008High — conformance movsx tests
REQ-ISA-006Byte swap operationsTC-ISA-014High — conformance be16/32/64, le16/32/64 tests
REQ-ISA-007Memory load/store and LDDWTC-ISA-005, TC-ISA-006High — ldx.data, st.data, stx.data, 80+ conformance tests (including lddw.data)
REQ-ISA-008Sign-extending loadsTC-ISA-007High — ldxsb-positive.data, ldxsh.data, conformance tests
REQ-ISA-009Jump instructions (64-bit and 32-bit)TC-ISA-009, TC-ISA-010High — jmp.data, 40+ conformance jmp/jmp32 tests
REQ-ISA-010Atomic operationsTC-ISA-011Medium — atomic_validate custom test (validation only)
REQ-ISA-011CALL instruction variantsTC-ISA-012High — call.data, factorial.data
REQ-ISA-012EXIT instructionTC-ISA-015High — early-exit.data, all tests terminate via EXIT

4.7 Security

REQ-IDRequirementTest CasesCoverage
REQ-SEC-001Bounds checkingTC-SEC-001High — 10+ error tests (err-stack-oob, err-address-*)
REQ-SEC-002Bounds check toggleTC-SEC-010Medium — implicitly tested (bounds on by default); [GAP: no explicit toggle test]
REQ-SEC-003Undefined behavior detection (shadow stack & registers)TC-SEC-002, TC-SEC-008, TC-SEC-009Low[GAP: no explicit UB detection, shadow stack, or shadow register tests]
REQ-SEC-004Constant blindingTC-SEC-003High — constant_blinding custom test, CI env var
REQ-SEC-005Read-only bytecodeTC-SEC-004Medium — readonly_bytecode custom test (toggles mode; [GAP: no test verifying pages are actually read-only])
REQ-SEC-006Pointer secret / XOR encodingTC-SEC-005Low[GAP: no test verifying XOR encoding effectiveness]
REQ-SEC-007RetpolinesTC-SEC-006Medium — CI runs with/without retpolines; no functional test
REQ-SEC-008W⊕X enforcementTC-SEC-007Medium — implicitly tested by JIT execution
REQ-SEC-009Custom bounds check callbackTC-EXT-005Low[GAP: no explicit custom bounds check test]

4.8 Extensibility

REQ-IDRequirementTest CasesCoverage
REQ-EXT-001Helper registrationTC-EXT-001High — call.data, call-memfrob.data, update_helpers
REQ-EXT-002Helper function limitTC-EXT-008Low[GAP: no test filling all 64 helper slots]
REQ-EXT-003External dispatcherTC-EXT-002High — 3 dispatcher custom tests
REQ-EXT-004Data relocation callbackTC-EXT-004Medium — tested via ELF loading
REQ-EXT-005Stack usage calculatorTC-EXT-006High — 3 custom_local_function_stack_size tests
REQ-EXT-006Debug functionTC-EXT-007High — debug_function custom test
REQ-EXT-007Unwind functionTC-EXT-003High — call_unwind.data

4.9 Configuration

REQ-IDRequirementTest CasesCoverage
REQ-CFG-001Error print redirectionTC-CFG-001Medium — used in custom tests but not directly tested
REQ-CFG-002JIT buffer sizingTC-CFG-002High — jit_buffer_too_small custom test
REQ-CFG-003Instruction limitTC-CFG-003Low[GAP: no instruction limit test]
REQ-CFG-004Register access (get/set)TC-CFG-004Low[GAP: no get/set register test]

4.10 Platform

REQ-IDRequirementTest CasesCoverage
REQ-PLAT-001Windows supportTC-PLAT-001High — CI: windows-2022, Debug + Release
REQ-PLAT-002Linux supportTC-PLAT-002High — CI: ubuntu-latest, coverage + sanitizers
REQ-PLAT-003macOS supportTC-PLAT-003High — CI: macos-latest
REQ-PLAT-004JIT architecture support (x86-64)TC-PLAT-004High — CI on all x86-64 platforms
REQ-PLAT-005Cryptographic random generationTC-PLAT-007Low[GAP: no dedicated test verifies RNG output or fallback behavior]
REQ-PLAT-006Platform atomic operationsTC-PLAT-008Medium — atomic_validate custom test; [GAP: no cross-platform atomic correctness test]

4.11 Error Handling

REQ-IDRequirementTest CasesCoverage
REQ-ERR-001Error message allocationTC-ERR-001High — error tests check stderr output
REQ-ERR-002Error output functionTC-ERR-002Medium — used but not directly validated
REQ-ERR-003Toggle return valuesTC-ERR-003Medium — toggles used in custom tests

4.12 Constants

REQ-IDRequirementTest CasesCoverage
REQ-CONST-001System constantsTC-CONST-001Medium — constants used throughout tests but not boundary-tested

4.13 Safe Interpreter Profile

REQ-IDRequirementTest CasesCoverage
REQ-SAFE-001Additive safe execution profileTC-SAFE-001High — safe-profile opt-in, immutability-after-load, interpreter-only execution, and legacy-vs-safe interpreter parity are covered in both local conformance runs and generated CTest cases
REQ-SAFE-002Tagged register provenance modelTC-SAFE-002Medium — stack-root and no-input-memory behavior are exercised indirectly, but explicit entry-state checks for R0/R3-R9 and R1-without-mem remain open
REQ-SAFE-003Provenance-checked memory access choke pointsTC-SAFE-003Medium — pointer-backed loads/stores and opaque-handle rejection are covered; atomic-result scalar classification still needs direct coverage
REQ-SAFE-004Pointer arithmetic and tag propagationTC-SAFE-004High — pointer add/subtract success and failure matrix, ALU32 tag clearing, and the common stack-frame address-computation idiom are covered
REQ-SAFE-005Typed helper metadata and return provenanceTC-SAFE-005Medium — typed pointer return success and missing-metadata rejection are covered; scalar-return and out-of-bounds return cases remain open
REQ-SAFE-006Descriptor-based external region metadataTC-SAFE-006Low — single-region descriptor resolution is covered, but multi-region distinction and legacy-bounds-callback insufficiency are still gaps
REQ-SAFE-007Spill and call-frame provenance preservationTC-SAFE-007Medium — spill restore, spill invalidation, and caller-saved reclassification are covered; direct callee-saved provenance restoration remains open
REQ-SAFE-008Initial safe-profile JIT unavailabilityTC-SAFE-008High — explicit compile rejection is covered by a dedicated custom test

5. Test Cases

TC-LIFE — VM Lifecycle

TC-LIFE-001: VM Creation

  • Traces to: REQ-LIFE-001
  • Level: Unit
  • Confidence: High
  • Evidence: Every test implicitly calls ubpf_create() / ubpf_destroy()
  • Pass criteria: VM pointer is non-NULL, all subsequent operations succeed
  • Existing tests: All test_vm.py, test_jit.py tests

TC-LIFE-002: VM Destruction / Memory Leaks

  • Traces to: REQ-LIFE-005
  • Level: Integration
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_reload_code_memleak.cc, Valgrind CI job
  • Pass criteria: No memory leaks reported by Valgrind; reload_code_memleak returns 0
  • Existing tests: reload_code_memleak-Custom, Valgrind CI workflow

TC-LIFE-003: Code Unloading and Reloading

  • Traces to: REQ-LIFE-006, REQ-LOAD-003
  • Level: Integration
  • Confidence: High
  • Evidence: tests/reload.data, tests/unload_reload.data
  • Pass criteria: VM accepts new code after unload; second execution produces correct result
  • Existing tests: test_vm reload/unload_reload tests

TC-LIFE-004: Default Configuration Values

  • Traces to: REQ-LIFE-002
  • Level: Unit
  • Confidence: Medium
  • Evidence: Tested indirectly — defaults produce expected behavior in standard tests
  • Pass criteria: Bounds checking enabled, constant blinding disabled, read-only mode enabled
  • [GAP]: No test explicitly verifies each default value after ubpf_create()

TC-LIFE-005: Platform JIT Selection

  • Traces to: REQ-LIFE-004
  • Level: System
  • Confidence: High
  • Evidence: CI matrix runs JIT tests on x86-64 (Windows/Linux/macOS) and ARM64
  • Pass criteria: JIT compilation succeeds on supported platforms

TC-LIFE-006: Memory Allocation Failure

  • Traces to: REQ-LIFE-003
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test injects allocation failures. Would require mock allocator or ulimit.

TC-LOAD — Program Loading

TC-LOAD-001: Double-Load Prevention

  • Traces to: REQ-LOAD-003
  • Level: Unit
  • Confidence: High
  • Evidence: All .data tests call ubpf_load as part of normal flow
  • Pass criteria: Loading code into a VM that already has code loaded returns an error
  • Existing tests: All data-driven tests (implicit)

TC-LOAD-002: Code Length Validation

  • Traces to: REQ-LOAD-001
  • Level: Unit
  • Confidence: Medium
  • [GAP]: No test for loading code with length that is not a multiple of 8 bytes.

TC-LOAD-003: Maximum Instruction Count

  • Traces to: REQ-LOAD-002
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test with 65536+ instructions to verify the maximum instruction count limit.

TC-LOAD-004: Instruction Validation

  • Traces to: REQ-LOAD-004, REQ-LOAD-010, REQ-LOAD-011
  • Level: Unit
  • Confidence: High
  • Evidence: tests/errors/* invalid instruction tests, atomic_validate custom test
  • Pass criteria: Invalid instructions, out-of-range jump targets, and unpaired LDDW are rejected at load time
  • Existing tests: tests/errors/*, atomic_validate-Custom

TC-LOAD-005: Stack Alignment Validation

  • Traces to: REQ-LOAD-008
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_custom_local_function_stack_size.cc and unaligned variant
  • Pass criteria: Unaligned stack sizes are rejected
  • Existing tests: custom_local_function_stack_size-Custom, custom_local_function_stack_size_unaligned-Custom

TC-LOAD-006: Sub-Program Containment

  • Traces to: REQ-LOAD-009
  • Level: Unit
  • Confidence: Medium
  • Evidence: Tested via local function call tests that validate sub-programs stay within bounds
  • Pass criteria: Sub-programs that exceed the program boundary are rejected
  • Existing tests: Local call tests (indirect)

TC-LOAD-007: Read-Only Bytecode Storage (Enabled)

  • Traces to: REQ-LOAD-005
  • Level: Unit
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_readonly_bytecode.cc
  • Pass criteria: Bytecode pages are marked read-only when feature is enabled
  • Existing tests: readonly_bytecode-Custom
  • [GAP]: No test verifying pages are actually read-only (e.g., via write-and-trap).

TC-LOAD-008: Read-Only Bytecode Storage (Disabled)

  • Traces to: REQ-LOAD-005
  • Level: Unit
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_readonly_bytecode.cc toggles mode
  • Pass criteria: Bytecode is writable when read-only mode is disabled
  • Existing tests: readonly_bytecode-Custom

TC-LOAD-009: Pointer Secret Encoding

  • Traces to: REQ-LOAD-006
  • Level: Unit
  • Confidence: Medium
  • [GAP]: No direct test of pointer secret encoding correctness. Encoding is exercised implicitly via all interpreter tests.

TC-LOAD-010: Local Function Marking

  • Traces to: REQ-LOAD-007
  • Level: Unit
  • Confidence: High
  • Evidence: tests/extensions/call_local_use_stack.data, tests/factorial.data
  • Pass criteria: Local functions are correctly identified and callable
  • Existing tests: call_local_use_stack, factorial

TC-ELF — ELF Loading

TC-ELF-001: ELF Wrapper Functions

  • Traces to: REQ-ELF-006
  • Level: System
  • Confidence: High
  • Evidence: test_framework/test_elf.py runs ELF-based tests
  • Pass criteria: ubpf_load_elf() successfully loads valid ELF files and programs execute correctly
  • Existing tests: test_elf.py

TC-ELF-002: ELF Header Validation

  • Traces to: REQ-ELF-001
  • Level: Unit
  • Confidence: Medium
  • [GAP]: No tests with malformed ELF headers (wrong magic, wrong class, wrong machine type).

TC-ELF-003: ELF Bounds Checking

  • Traces to: REQ-ELF-003
  • Level: Unit
  • Confidence: High
  • Evidence: tests/elf/ directory contains ELF-specific test programs
  • Pass criteria: Out-of-bounds section references in ELF files are rejected
  • Existing tests: tests/elf/*

TC-ELF-004: R_BPF_64_64 Data Relocation

  • Traces to: REQ-ELF-004
  • Level: Integration
  • Confidence: High
  • Evidence: bpf/rel_64_32.bpf.c, tests/elf/ relocation tests
  • Pass criteria: 64-bit data relocations are resolved correctly
  • Existing tests: tests/elf/*, bpf/rel_64_32.bpf.c

TC-ELF-005: R_BPF_64_32 Helper Relocation

  • Traces to: REQ-ELF-005
  • Level: Integration
  • Confidence: High
  • Evidence: Conformance suite helper tests exercise helper relocations
  • Pass criteria: 32-bit helper function relocations are resolved correctly
  • Existing tests: Conformance helper tests

TC-ELF-006: Multi-Function ELF Linking

  • Traces to: REQ-ELF-007
  • Level: Integration
  • Confidence: Medium
  • Evidence: Multi-function ELF programs tested via ELF loader
  • Pass criteria: Multiple functions within an ELF are correctly linked and callable
  • Existing tests: Multi-function ELF programs (indirect)

TC-ELF-007: Main Function Selection

  • Traces to: REQ-ELF-007
  • Level: Integration
  • Confidence: Medium
  • [GAP]: No explicit test for named-main function selection in multi-function ELF files.

TC-ELF-008: Section Count Limit

  • Traces to: REQ-ELF-002
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test with >32 sections to verify the section count limit is enforced.

TC-EXEC — Execution

TC-EXEC-001: Interpreter Execution (Data-Driven)

  • Traces to: REQ-EXEC-001, REQ-EXEC-003, REQ-EXEC-007
  • Level: Unit
  • Confidence: High
  • Evidence: test_framework/test_vm.py — runs every .data file through interpreter
  • Pass criteria: Return value matches -- result section; errors match -- error section
  • Existing tests: 104 repository .data files via test_vm.py, plus 417 plugin-driven interpreter runs (104 local + 313 conformance)

TC-EXEC-002: Extended Interpreter Entry Point

  • Traces to: REQ-EXEC-002
  • Level: Unit
  • Confidence: Medium
  • [GAP]: Limited direct exec_ex tests. No dedicated test exercises ubpf_exec_ex() API independently from standard ubpf_exec().

TC-EXEC-003: Register Initialization

  • Traces to: REQ-EXEC-003
  • Level: Unit
  • Confidence: High
  • Evidence: Memory and result comparison in all data-driven tests validates correct r1/r2 initialization
  • Pass criteria: r1 points to memory input, r2 contains memory length, r0 returns correct result
  • Existing tests: All local test_vm.py data-driven tests plus plugin-driven interpreter coverage

TC-EXEC-004: Code-Not-Loaded Guard and XOR-Decoded Fetch

  • Traces to: REQ-EXEC-004, REQ-EXEC-007
  • Level: Unit
  • Confidence: Medium
  • Evidence: XOR decode is implicit in all 360+ data-driven tests (instructions are encoded on load)
  • Pass criteria: Execution without loaded code returns error; XOR-decoded instructions execute correctly
  • [GAP]: No explicit test for executing without loading code first.

TC-EXEC-005: ALU Operations

  • Traces to: REQ-ISA-003, REQ-ISA-004
  • Level: Unit
  • Confidence: High
  • Evidence: tests/alu.data, tests/alu64.data, tests/sdiv32.data, tests/sdiv64.data, tests/smod32.data, tests/smod64.data, tests/arsh*.data, 100+ conformance ALU tests
  • Pass criteria: Correct arithmetic results for all operations, all operand types
  • Existing tests: Comprehensive coverage of ADD, SUB, MUL, DIV, MOD, OR, AND, XOR, LSH, RSH, ARSH, NEG, MOV, SDIV, SMOD

TC-EXEC-006: Memory Bounds Checking

  • Traces to: REQ-SEC-001
  • Level: Unit
  • Confidence: High
  • Evidence: tests/errors/err-stack-oob.data, tests/errors/err-address-overflow-offset.data, tests/errors/err-address-underflow.data, tests/errors/err-integer-overflow-bounds.data
  • Pass criteria: Out-of-bounds access produces error (non-zero exit, error message)
  • Existing tests: 4+ dedicated error tests

TC-EXEC-007: Local Function Calls

  • Traces to: REQ-EXEC-006
  • Level: Integration
  • Confidence: High
  • Evidence: tests/factorial.data, tests/extensions/call_local_use_stack.data, tests/stack2.data, tests/stack3.data, custom_local_function_stack_size tests
  • Pass criteria: Correct return values; callee-saved registers (r6-r9) preserved; frame pointer (r10) adjusted correctly
  • Existing tests: 5+ tests covering local calls

TC-EXEC-008: External Helper Calls

  • Traces to: REQ-EXEC-008, REQ-EXT-001
  • Level: Integration
  • Confidence: High
  • Evidence: tests/helpers/call.data, tests/helpers/call-memfrob.data, tests/helpers/call-save.data
  • Pass criteria: Helper receives correct parameters; return value propagated to r0
  • Existing tests: 3 dedicated helper tests + conformance call tests

TC-EXEC-009: Instruction Limit Enforcement

  • Traces to: REQ-EXEC-005
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test currently exercises ubpf_set_instruction_limit(). Should verify interpreter stops after N instructions.

TC-EXEC-010: Debug Callback Invocation

  • Traces to: REQ-EXEC-009
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_debug_function.cc
  • Pass criteria: Debug callback invoked before each instruction with correct PC, registers, and stack info
  • Existing tests: debug_function-Custom

TC-ISA — Instruction Set Architecture

TC-ISA-001: Instruction Format

  • Traces to: REQ-ISA-001
  • Level: Unit
  • Confidence: High
  • Evidence: Assembler/raw comparison in all .data tests validates instruction encoding
  • Pass criteria: Instructions are correctly encoded and decoded in the 8-byte format
  • Existing tests: 104 local data-driven tests plus plugin-driven coverage over the 313-test conformance suite

TC-ISA-002: Register Model

  • Traces to: REQ-ISA-002
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_frame_pointer.cc, JIT register offset variants
  • Pass criteria: All 11 registers (r0-r10) function correctly; r10 is read-only frame pointer
  • Existing tests: frame_pointer-Custom, JIT offset tests

TC-ISA-003: ALU64 Operations

  • Traces to: REQ-ISA-003
  • Level: Unit
  • Confidence: High
  • Evidence: tests/alu64.data, 50+ conformance ALU64 tests
  • Pass criteria: All 64-bit ALU operations produce correct results
  • Existing tests: alu64, conformance ALU64 tests

TC-ISA-004: ALU32 Operations

  • Traces to: REQ-ISA-003
  • Level: Unit
  • Confidence: High
  • Evidence: tests/alu.data, 50+ conformance ALU32 tests
  • Pass criteria: All 32-bit ALU operations produce correct results with zero-extension
  • Existing tests: alu, conformance ALU32 tests

TC-ISA-005: Memory Load/Store

  • Traces to: REQ-ISA-007
  • Level: Unit
  • Confidence: High
  • Evidence: tests/ldx.data, tests/st.data, tests/stx.data, 80+ conformance memory tests
  • Pass criteria: All memory load and store operations at all widths (8/16/32/64) produce correct results
  • Existing tests: ldx, st, stx, conformance memory tests

TC-ISA-006: LDDW (64-bit Immediate Load)

  • Traces to: REQ-ISA-007
  • Level: Unit
  • Confidence: High
  • Evidence: external/bpf_conformance/tests/lddw.data, conformance LDDW tests
  • Pass criteria: 64-bit immediate values are correctly loaded via two-instruction LDDW
  • Existing tests: lddw, conformance LDDW tests

TC-ISA-007: Sign-Extending Loads

  • Traces to: REQ-ISA-008
  • Level: Unit
  • Confidence: High
  • Evidence: tests/ldxsb-positive.data, tests/ldxsh.data, conformance sign-extension tests
  • Pass criteria: Sign-extending loads correctly extend signed values to 64 bits
  • Existing tests: ldxsb-positive, ldxsh, conformance tests

TC-ISA-008: MOVSX (Sign-Extending Move)

  • Traces to: REQ-ISA-005
  • Level: Unit
  • Confidence: High
  • Evidence: Conformance MOVSX tests
  • Pass criteria: MOVSX instructions correctly sign-extend source to destination register
  • Existing tests: Conformance MOVSX tests

TC-ISA-009: Jump Instructions (64-bit)

  • Traces to: REQ-ISA-009
  • Level: Unit
  • Confidence: High
  • Evidence: tests/jmp.data, 40+ conformance jump tests
  • Pass criteria: All conditional and unconditional jumps with 64-bit comparisons branch correctly
  • Existing tests: jmp, conformance jump tests

TC-ISA-010: JMP32 (32-bit Jumps)

  • Traces to: REQ-ISA-009
  • Level: Unit
  • Confidence: High
  • Evidence: Conformance JMP32 tests
  • Pass criteria: All conditional jumps with 32-bit comparisons branch correctly
  • Existing tests: Conformance JMP32 tests

TC-ISA-011: Atomic Operations

  • Traces to: REQ-ISA-010
  • Level: Unit
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_atomic_validate.cc (validation only)
  • Pass criteria: Atomic instructions are validated at load time
  • Existing tests: atomic_validate-Custom
  • [GAP]: No runtime execution test for atomic operations; only validation is tested.

TC-ISA-012: CALL Instruction

  • Traces to: REQ-ISA-011
  • Level: Unit
  • Confidence: High
  • Evidence: tests/helpers/call.data, tests/factorial.data
  • Pass criteria: CALL instruction correctly invokes helper functions and local functions
  • Existing tests: call, factorial

TC-ISA-013: Signed Division and Modulo

  • Traces to: REQ-ISA-004
  • Level: Unit
  • Confidence: High
  • Evidence: tests/sdiv32.data, tests/sdiv64.data, tests/smod32.data, tests/smod64.data
  • Pass criteria: Signed division and modulo produce correct results including negative operands
  • Existing tests: sdiv32, sdiv64, smod32, smod64

TC-ISA-014: Byte Swap Operations

  • Traces to: REQ-ISA-006
  • Level: Unit
  • Confidence: High
  • Evidence: Conformance BE16/32/64, LE16/32/64 tests
  • Pass criteria: Byte swap operations correctly convert endianness at all widths
  • Existing tests: Conformance BE/LE tests

TC-ISA-015: EXIT Instruction

  • Traces to: REQ-ISA-012
  • Level: Unit
  • Confidence: High
  • Evidence: tests/early-exit.data, all tests terminate via EXIT instruction
  • Pass criteria: EXIT instruction terminates execution and returns r0
  • Existing tests: early-exit, all data-driven tests

TC-JIT — JIT Compilation

TC-JIT-001: JIT Execution Correctness

  • Traces to: REQ-JIT-001, REQ-JIT-002
  • Level: System
  • Confidence: High
  • Evidence: test_framework/test_jit.py — runs every .data file through JIT with 20 register-offset variants
  • Pass criteria: JIT output matches interpreter output for all tests
  • Existing tests: 104 local .data files with up to 20 register-offset variants, plus 417 plugin-driven JIT runs (104 local + 313 conformance)

TC-JIT-002: compile_ex API

  • Traces to: REQ-JIT-002
  • Level: Integration
  • Confidence: Medium
  • Evidence: ubpf_plugin in ExtendedJitMode exercises ubpf_compile_ex()
  • Pass criteria: Extended JIT compilation API succeeds and produces executable code
  • Existing tests: ubpf_plugin ExtendedJitMode tests

TC-JIT-003: BasicJitMode

  • Traces to: REQ-JIT-002
  • Level: System
  • Confidence: High
  • Evidence: Default mode in test_framework/test_jit.py
  • Pass criteria: JIT compilation in basic mode produces correct results for all tests
  • Existing tests: test_jit.py (default mode)

TC-JIT-004: ExtendedJitMode

  • Traces to: REQ-JIT-002
  • Level: System
  • Confidence: Medium
  • Evidence: ubpf_plugin with --jit flag exercises extended JIT mode
  • Pass criteria: JIT compilation in extended mode produces correct results
  • Existing tests: ubpf_plugin with --jit

TC-JIT-005: Code Caching

  • Traces to: REQ-JIT-003
  • Level: Unit
  • Confidence: Low
  • [GAP]: No explicit caching test. No test verifies that compiled JIT code is reused across invocations.

TC-JIT-006: W⊕X Memory

  • Traces to: REQ-JIT-004
  • Level: Integration
  • Confidence: Medium
  • Evidence: Implicit; ASan would catch memory protection violations
  • Pass criteria: JIT-compiled code memory is not simultaneously writable and executable
  • Existing tests: All JIT tests with ASan (implicit)

TC-JIT-007: translate API

  • Traces to: REQ-JIT-007
  • Level: Unit
  • Confidence: Low
  • [GAP]: No direct test of the ubpf_translate() API for outputting JIT code to an external buffer.

TC-JIT-008: copy_jit API

  • Traces to: REQ-JIT-006
  • Level: Unit
  • Confidence: Medium
  • Evidence: ubpf_plugin/ubpf_plugin.cc copies JIT output into an executable mapping and executes the copy, comparing it with the original JIT result.
  • Pass criteria: Copied JIT code executes independently and matches the original JIT result.
  • [GAP]: No dedicated unit test isolates ubpf_copy_jit() failure modes beyond the plugin path.

TC-JIT-009: x86-64 Dual ABI

  • Traces to: REQ-JIT-009
  • Level: System
  • Confidence: High
  • Evidence: CI runs JIT tests on both Windows (Win64 ABI) and Linux (System V ABI)
  • Pass criteria: Same tests pass on both platforms
  • Existing tests: CI matrix covers both ABIs

TC-JIT-010: ARM64 Backend Support

  • Traces to: REQ-JIT-010
  • Level: System
  • Confidence: High
  • Evidence: CI on ARM64 (native + QEMU emulation)
  • Pass criteria: JIT compilation and execution succeeds on ARM64 architecture
  • Existing tests: CI matrix (ARM64 native and QEMU)

TC-JIT-011: JIT Buffer Too Small

  • Traces to: REQ-JIT-005, REQ-CFG-002
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_jit_buffer_too_small.cc
  • Pass criteria: JIT compilation fails gracefully with error message
  • Existing tests: jit_buffer_too_small-Custom

TC-JIT-012: Instruction Limit Non-Applicability

  • Traces to: REQ-JIT-008
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test verifying that ubpf_set_instruction_limit() does not affect JIT execution.

TC-JIT-013: Post-Compilation Helper Update

  • Traces to: REQ-JIT-011
  • Level: Integration
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_update_helpers.cc, ubpf_test_update_dispatcher.cc
  • Pass criteria: Helpers/dispatcher can be updated after JIT compilation; updated functions are called
  • Existing tests: update_helpers-Custom, update_dispatcher-Custom

TC-SEC — Security

TC-SEC-001: Bounds Check Enforcement

  • Traces to: REQ-SEC-001
  • Level: Unit
  • Confidence: High
  • Evidence: tests/errors/err-stack-oob.data and related error tests
  • Pass criteria: OOB access rejected with error
  • Existing tests: 10+ error condition tests

TC-SEC-003: Constant Blinding

  • Traces to: REQ-SEC-004
  • Level: Integration
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_constant_blinding.cc, CI runs with UBPF_ENABLE_CONSTANT_BLINDING=1
  • Pass criteria: JIT produces correct results with blinding enabled; all CTest passes with blinding
  • Existing tests: constant_blinding-Custom, CI environment flag

TC-SEC-004: Read-Only Bytecode

  • Traces to: REQ-SEC-005
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_readonly_bytecode.cc
  • Pass criteria: Bytecode stored in read-only pages; toggling mode works correctly
  • Existing tests: readonly_bytecode-Custom

TC-SEC-005: Pointer Secret / XOR Encoding

  • Traces to: REQ-SEC-006
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test verifying XOR encoding effectiveness or that pointer secret changes instruction storage.

TC-SEC-006: Retpolines

  • Traces to: REQ-SEC-007
  • Level: System
  • Confidence: Medium
  • Evidence: CI runs both with and without UBPF_DISABLE_RETPOLINES
  • Pass criteria: Tests pass in both configurations
  • Existing tests: CI matrix (no dedicated functional test)

TC-SEC-007: W⊕X Enforcement

  • Traces to: REQ-SEC-008
  • Level: Integration
  • Confidence: Medium
  • Evidence: JIT code executes successfully; ASan/Valgrind would detect violations
  • Pass criteria: JIT memory is executable but not writable during execution
  • Existing tests: Implicitly tested by all JIT tests

TC-SEC-010: Bounds Check Toggle

  • Traces to: REQ-SEC-002
  • Level: Unit
  • Confidence: Medium
  • [GAP]: No explicit test toggling bounds checking off and verifying behavior change.

TC-SEC-002: Undefined Behavior Detection

  • Traces to: REQ-SEC-003
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test enabling UB detection and verifying uninitialized register/stack reads are flagged.

TC-SEC-008: Shadow Stack

  • Traces to: REQ-SEC-003
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test verifying shadow stack bit tracking (marks on write, checks on read).

TC-SEC-009: Shadow Registers

  • Traces to: REQ-SEC-003
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test verifying shadow register bitmask tracking for uninitialized register detection.

TC-EXT — Extensibility

TC-EXT-001: Helper Registration

  • Traces to: REQ-EXT-001
  • Level: Unit
  • Confidence: High
  • Evidence: tests/helpers/call.data, tests/helpers/call-memfrob.data, custom_tests/srcs/ubpf_test_update_helpers.cc
  • Pass criteria: Helper functions are registered and callable by BPF programs via CALL instruction
  • Existing tests: call, call-memfrob, update_helpers-Custom

TC-EXT-002: External Dispatcher

  • Traces to: REQ-EXT-003
  • Level: Integration
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_external_dispatcher_simple_context.cc, ubpf_test_external_dispatcher_context_overwrite.cc, ubpf_test_default_dispatcher_helper_context.cc, ubpf_test_update_dispatcher.cc
  • Pass criteria: Dispatcher receives correct parameters; context handling correct; updates work
  • Existing tests: 4 custom tests

TC-EXT-003: Unwind Function

  • Traces to: REQ-EXT-007
  • Level: Unit
  • Confidence: High
  • Evidence: tests/extensions/call_unwind.data
  • Pass criteria: Unwind function is called on error; execution terminates with correct error code
  • Existing tests: call_unwind

TC-EXT-004: Data Relocation Callback

  • Traces to: REQ-EXT-004
  • Level: Integration
  • Confidence: Medium
  • Evidence: Tested via ELF loading pipeline
  • Pass criteria: Data relocation callback is invoked for map references during ELF loading
  • Existing tests: ELF loading tests (indirect)

TC-EXT-005: Custom Bounds Check Callback

  • Traces to: REQ-SEC-009
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test registering a custom bounds check callback via ubpf_register_data_bounds_check() and verifying it is invoked during memory access.

TC-EXT-006: Stack Usage Calculator

  • Traces to: REQ-EXT-005
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_custom_local_function_stack_size.cc, *_unaligned.cc, *_zero.cc, ubpf_test_default_local_function_stack_size.cc
  • Pass criteria: Custom stack sizes applied; unaligned rejected; zero accepted; default works
  • Existing tests: 4 custom tests

TC-EXT-007: Debug Function

  • Traces to: REQ-EXT-006
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_debug_function.cc
  • Pass criteria: Debug function callback is invoked before each instruction with correct state
  • Existing tests: debug_function-Custom

TC-EXT-008: Helper Function Limit

  • Traces to: REQ-EXT-002
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test filling all 64 helper slots to verify the helper function registration limit.

TC-CFG — Configuration

TC-CFG-001: Error Print Redirection

  • Traces to: REQ-CFG-001
  • Level: Unit
  • Confidence: Medium
  • Evidence: Used in custom tests but not directly tested for correctness
  • Pass criteria: Error output is redirected to the configured print function
  • Existing tests: Custom tests (indirect)

TC-CFG-002: JIT Buffer Sizing

  • Traces to: REQ-CFG-002
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_jit_buffer_too_small.cc
  • Pass criteria: JIT buffer size can be configured; undersized buffer causes compilation failure
  • Existing tests: jit_buffer_too_small-Custom

TC-CFG-003: Instruction Limit

  • Traces to: REQ-CFG-003
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test exercises ubpf_set_instruction_limit() to verify instruction count limiting.

TC-CFG-004: Register Access

  • Traces to: REQ-CFG-004
  • Level: Unit
  • Confidence: Low
  • [GAP]: No test exercises get/set register APIs to verify register access functionality.

TC-PLAT — Platform Support

TC-PLAT-001: Windows Support

  • Traces to: REQ-PLAT-001
  • Level: System
  • Confidence: High
  • Evidence: CI: windows-2022, Debug + Release configurations
  • Pass criteria: All tests pass on Windows with MSVC
  • Existing tests: CI matrix (windows-2022)

TC-PLAT-002: Linux Support

  • Traces to: REQ-PLAT-002
  • Level: System
  • Confidence: High
  • Evidence: CI: ubuntu-latest, coverage + sanitizers (ASan, UBSan)
  • Pass criteria: All tests pass on Linux with GCC/Clang; no sanitizer violations
  • Existing tests: CI matrix (ubuntu-latest)

TC-PLAT-003: macOS Support

  • Traces to: REQ-PLAT-003
  • Level: System
  • Confidence: High
  • Evidence: CI: macos-latest
  • Pass criteria: All tests pass on macOS
  • Existing tests: CI matrix (macos-latest)

TC-PLAT-004: x86-64 JIT

  • Traces to: REQ-PLAT-004
  • Level: System
  • Confidence: High
  • Evidence: CI runs JIT tests on all x86-64 platforms (Windows, Linux, macOS)
  • Pass criteria: JIT compilation and execution succeeds on x86-64
  • Existing tests: CI matrix (all x86-64 platforms)

TC-PLAT-007: Crypto RNG

  • Traces to: REQ-PLAT-005
  • Level: System
  • Confidence: Low
  • Evidence: Source inspection shows platform branches in vm/ubpf_jit_support.c, but no dedicated runtime assertion validates RNG output or fallback selection.
  • [GAP]: No test verifies BCryptGenRandom, getrandom, arc4random_buf, or the rand() fallback behavior.

TC-PLAT-008: Platform Atomics

  • Traces to: REQ-PLAT-006
  • Level: System
  • Confidence: Medium
  • [GAP]: No cross-platform atomic correctness test. Atomics are compiled but not tested for cross-platform behavior.

TC-ERR — Error Handling

TC-ERR-001: Error Message Allocation

  • Traces to: REQ-ERR-001
  • Level: Unit
  • Confidence: High
  • Evidence: Error tests check stderr output for correct error messages
  • Pass criteria: Error messages are allocated and returned correctly via the error string parameter
  • Existing tests: tests/errors/* (error message verification)

TC-ERR-002: Error Output Function

  • Traces to: REQ-ERR-002
  • Level: Unit
  • Confidence: Medium
  • Evidence: Error output function is used but not directly validated for correct invocation
  • Pass criteria: Custom error output function receives formatted error messages
  • Existing tests: Custom tests (indirect)

TC-ERR-003: Toggle Return Values

  • Traces to: REQ-ERR-003
  • Level: Unit
  • Confidence: Medium
  • Evidence: Toggle functions return values are used in custom tests
  • Pass criteria: Toggle functions return previous state value
  • Existing tests: Custom tests (indirect)

TC-CONST — Constants

TC-CONST-001: System Constants

  • Traces to: REQ-CONST-001
  • Level: Unit
  • Confidence: Medium
  • Evidence: Constants (MAX_INSTS, STACK_SIZE, etc.) are used throughout tests but not boundary-tested
  • Pass criteria: System constants are correctly defined and enforced at boundaries
  • Existing tests: All tests (indirect usage)

TC-SAFE — Safe Interpreter Profile

TC-SAFE-001: Safe-Profile Compatibility Gate

  • Traces to: REQ-SAFE-001
  • Level: Integration
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_safe_profile_compile_rejection.cc; ubpf_plugin/CMakeLists.txt; ubpf_plugin/ubpf_plugin.cc exercised against external/bpf_conformance/tests with --profile legacy --interpret and --profile safe --interpret
  • Pass criteria: ubpf_set_execution_profile() opts a VM into safe mode before load, rejects profile changes after load, and leaves interpreter execution available while JIT remains rejected.
  • Existing tests: ubpf_test_safe_profile_compile_rejection-Custom; per-file *-Interpreter and *-Safe-Interpreter CTest cases generated from external/bpf_conformance/tests/*.data and tests/*.data
  • Remaining gap: Extend parity coverage beyond the default v3 interpreter matrix to typed-pointer helper scenarios that require region descriptors.

TC-SAFE-002: Root Provenance Initialization

  • Traces to: REQ-SAFE-002
  • Level: Unit
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_safe_profile_spills_and_local_calls.cc, custom_tests/srcs/ubpf_test_safe_profile_pointer_arithmetic.cc
  • Pass criteria: Safe-profile entry initializes stack-root provenance correctly, rejects use of reclassified scalars as pointers, and preserves only explicit provenance-bearing values.
  • Existing tests: ubpf_test_safe_profile_spills_and_local_calls-Custom, ubpf_test_safe_profile_pointer_arithmetic-Custom
  • Remaining gap: Add explicit checks for R0/R3-R9 scalar entry state and for R1 being scalar when mem == NULL.

TC-SAFE-003: Safe Dereference Choke Points

  • Traces to: REQ-SAFE-003
  • Level: Unit
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_safe_profile_helpers.cc, custom_tests/srcs/ubpf_test_safe_profile_spills_and_local_calls.cc
  • Pass criteria: Safe-mode dereferences succeed only through pointer-tagged registers within region bounds; dereference through handles or reclassified scalars fails before host access.
  • Existing tests: ubpf_test_safe_profile_helpers-Custom, ubpf_test_safe_profile_spills_and_local_calls-Custom
  • Remaining gap: Add direct atomic coverage showing fetch-result registers are classified as scalars.

TC-SAFE-004: Pointer Arithmetic Matrix

  • Traces to: REQ-SAFE-004
  • Level: Unit
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_safe_profile_pointer_arithmetic.cc, custom_tests/srcs/ubpf_test_safe_profile_spills_and_local_calls.cc, external/bpf_conformance/tests/stack.data
  • Pass criteria: Pointer-plus-pointer and scalar-minus-pointer fail, same-region pointer subtraction produces a scalar, different-region pointer subtraction fails, and pointer-plus-scalar / pointer-minus-scalar remain usable for valid stack access.
  • Existing tests: ubpf_test_safe_profile_pointer_arithmetic-Custom, ubpf_test_safe_profile_spills_and_local_calls-Custom; local bpf_conformance_runner execution of stack.data with --profile safe --interpret

TC-SAFE-005: Typed Helper Return Validation

  • Traces to: REQ-SAFE-005
  • Level: Integration
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_safe_profile_helpers.cc
  • Pass criteria: Helpers with safe descriptors can return typed pointers or handles, and helper calls without safe metadata fail before dispatch.
  • Existing tests: ubpf_test_safe_profile_helpers-Custom
  • Remaining gap: Add scalar-return and out-of-bounds-pointer negative cases.

TC-SAFE-006: External Region Descriptor Resolution

  • Traces to: REQ-SAFE-006
  • Level: Integration
  • Confidence: Low
  • Evidence: custom_tests/srcs/ubpf_test_safe_profile_helpers.cc
  • Pass criteria: Safe helper metadata resolves to registered region descriptors, and returned pointers remain constrained to their registered region.
  • Existing tests: ubpf_test_safe_profile_helpers-Custom
  • Remaining gap: Add two-disjoint-region coverage and a regression proving the legacy bool bounds callback alone does not establish provenance.

TC-SAFE-007: Spill and Local-Call Provenance

  • Traces to: REQ-SAFE-007
  • Level: Integration
  • Confidence: Medium
  • Evidence: custom_tests/srcs/ubpf_test_safe_profile_spills_and_local_calls.cc
  • Pass criteria: Full-width stack spills restore provenance, partial writes invalidate it, and caller-saved registers lose provenance on local-call return.
  • Existing tests: ubpf_test_safe_profile_spills_and_local_calls-Custom
  • Remaining gap: Add a direct callee-saved provenance-preservation case using R6-R9 across a local call.

TC-SAFE-008: Safe-Profile Compile Rejection

  • Traces to: REQ-SAFE-008
  • Level: Unit
  • Confidence: High
  • Evidence: custom_tests/srcs/ubpf_test_safe_profile_compile_rejection.cc
  • Pass criteria: ubpf_compile*() and ubpf_translate*() reject safe-profile VMs with an explicit interpreter-only error.
  • Existing tests: ubpf_test_safe_profile_compile_rejection-Custom

TC-FUZZ — Fuzzing

TC-FUZZ-001: Differential Interpreter/JIT Testing

  • Traces to: REQ-EXEC-007, REQ-JIT-001
  • Level: System
  • Confidence: High
  • Evidence: libfuzzer/libfuzz_harness.cc
  • Pass criteria: Interpreter and JIT produce identical results for all generated inputs
  • Existing tests: Daily 1-hour fuzzing runs, corpus regression in CI

TC-FUZZ-002: PREVAIL Verifier Integration

  • Traces to: REQ-EXEC-007
  • Level: System
  • Confidence: Medium
  • Evidence: libfuzzer/libfuzz_harness.cc with UBPF_FUZZER_VERIFY_BYTE_CODE=1
  • Pass criteria: Verifier-approved programs execute without crashes
  • Existing tests: Fuzzer with verifier enabled

6. Risk-Based Test Prioritization

6.1 Risk Categories

Risk IDCategoryImpactLikelihoodPriority
R1JIT produces incorrect resultsCritical — silent data corruptionMediumP1
R2Bounds check bypassCritical — arbitrary memory accessLowP1
R3Memory corruption in VMCritical — host process crashMediumP1
R4ELF loader accepts malformed inputHigh — potential code executionMediumP2
R5Constant blinding bypassHigh — JIT spraying attackLowP2
R6Platform-specific failuresMedium — limited to one platformMediumP2
R7Helper function parameter corruptionMedium — incorrect helper behaviorLowP3
R8Stack overflow in local callsMedium — program crashLowP3
R9Configuration API misuseLow — unexpected behaviorMediumP3
R10Safe-profile provenance bypassCritical — verifier-like memory safety defeatedMediumP1

6.2 Prioritization Rationale

P1 (Must test): JIT correctness, bounds checking, memory safety, and safe-profile provenance enforcement — these are the core security and correctness guarantees.

  • Covered by: Differential fuzzing (TC-FUZZ-001), error tests (TC-SEC-001), sanitizers (ASan/UBSan), Valgrind
  • Gap: Safe-profile provenance coverage exists, but direct regressions for null-input root state, multi-region descriptors, and legacy-vs-safe side-by-side behavior remain open

P2 (Should test): ELF robustness, constant blinding effectiveness, platform parity — important but lower likelihood.

  • Covered by: CI matrix (TC-PLAT-*), constant blinding tests (TC-SEC-003), some ELF tests
  • Gap: No adversarial ELF fuzzing

P3 (Nice to test): Helper correctness, stack depth, configuration edge cases — lower impact.

  • Covered by: Helper tests (TC-EXT-001), stack tests (TC-EXEC-007)
  • Gaps: Instruction limit, register get/set, deep call chains

7. Pass/Fail Criteria

7.1 Entry Criteria

Before test execution:

  • Code compiles successfully on all target platforms
  • All submodules initialized (git submodule update --init --recursive)
  • Test dependencies installed (Python: parcon, nose, pyelftools)
  • Environment configured (platform-specific build prerequisites)

7.2 Exit Criteria

Test suite passes when:

  • All CTest tests pass on every CI platform (Windows, Linux, macOS, ARM64)
  • Zero ASan/UBSan violations in sanitizer builds
  • Zero Valgrind errors (Linux)
  • Fuzzer runs for 1 hour without finding new crashes
  • Code coverage does not decrease vs. previous baseline (Coveralls)

7.3 Acceptance Thresholds

MetricThresholdCurrent Status
CTest pass rate100%Enforced by CI
ASan violations0Enforced by CI
Valgrind errors0Enforced by CI (Linux)
Fuzzer crashes0 newEnforced by CI
Code coverageNon-decreasingTracked by Coveralls

8. Coverage Gap Summary

8.1 High-Priority Gaps

GapREQ-IDs AffectedRiskRecommendation
No UB detection testsREQ-SEC-003MediumAdd tests enabling UB checks, verify shadow stack/register detection
No instruction limit testREQ-CFG-003LowAdd test setting limit and verifying execution stops
No malformed ELF testsREQ-ELF-001MediumFuzz the ELF loader with invalid headers/sections
No register get/set testsREQ-CFG-004LowAdd test calling ubpf_set_registers/ubpf_get_registers
No custom bounds check testREQ-SEC-009MediumAdd test registering custom bounds check callback

8.2 Medium-Priority Gaps

GapREQ-IDs AffectedRiskRecommendation
No OOM handling testsREQ-LIFE-003LowTest with constrained memory or mock allocator
No explicit exec_ex testREQ-EXEC-002LowAdd test calling ubpf_exec_ex with custom stack
No translate/copy_jit testsREQ-JIT-007, REQ-JIT-006LowAdd tests for these less-used APIs
No JIT caching verificationREQ-JIT-003LowVerify compile returns same pointer on second call
No XOR encoding verificationREQ-LOAD-006, REQ-SEC-006MediumVerify instructions are XOR-encoded in memory
No direct safe-profile entry-state regression for null input memoryREQ-SAFE-002MediumAdd a test that dereferences R1 with mem == NULL and proves safe mode treats it as a scalar
No multi-region safe descriptor regressionREQ-SAFE-006MediumAdd two disjoint safe regions plus helper returns that prove provenance remains region-specific

8.3 Structural Gaps

GapImpactRecommendation
No concurrency testsUnknown thread safetyDefine thread-safety model, add tests
No stress testsUnknown scalability limitsTest with MAX_INSTS programs, deep call chains
No performance regressionSilent performance degradationAdd benchmark suite
No adversarial ELF fuzzingPotential loader vulnerabilitiesAdd ELF-specific fuzzer
Atomic operations: validation onlyCorrectness unverified at runtimeAdd atomic execution correctness tests

9. Revision History

VersionDateAuthorDescription
1.2.02026-06-12Evolve refreshAdded validation scope for the additive safe-interpreter profile, including planned coverage for provenance enforcement and safe-mode JIT rejection.
1.1.02026-06-12Bootstrap refreshReconciled current test inventory counts, credited indirect ubpf_copy_jit() coverage via ubpf_plugin, and downgraded overstated RNG coverage claims.
1.0.02026-03-31Extracted by AIInitial draft — mapped existing tests to requirements, identified gaps