Skip to content

Feat wasm verification#48

Merged
hbgit merged 47 commits into
developfrom
feat-wasm-verification
Jul 6, 2026
Merged

Feat wasm verification#48
hbgit merged 47 commits into
developfrom
feat-wasm-verification

Conversation

@GuilhermeBn198

Copy link
Copy Markdown
Collaborator

Summary

Pipeline WASM end-to-end validado: o Map2Check agora verifica binários .wasm diretamente via map2check --wasm, reaproveitando todo o pipeline LLVM 16 + KLEE existente. 15 casos da Juliet Test Suite (CWE-121/122/124/126/127) foram validados com 15/15 FALSE. Infraestrutura de CI completa com jobs de build, testes unitários, análise estática, sanitizers e novo job E2E com KLEE real em container Docker.

Motivation

O pipeline WASM estava implementado mas não validado empiricamente. Os resultados eram inconsistentes entre execuções locais e CI devido a 4 problemas críticos de infraestrutura:

  1. WABT 1.0.27 do apt vs 1.0.41 do Dockerfile.dev: wasm-rt.h do apt não tem wasm_rt_funcref_table_t nem bool is64 — WasmRuntimeStubs.c quebrava
  2. Build estático não acha Z3.so: CMAKE_FIND_LIBRARY_SUFFIXES=".a" impedia o build com KLEE em ambientes com Z3/STP apenas como bibliotecas compartilhadas
  3. Install rules incompletas: ninja install não copiava klee-uclibc.bca nem compiler-rt, causando crash do KLEE no E2E
  4. Timeout insuficiente: 110s produzia UNKNOWN em todos os casos Juliet; 290s permite exploração suficiente para encontrar as violações

Type of change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • This change requires a documentation update

How Has This Been Tested?

  • CI GitHub Actions: jobs build-and-test, static-analysis, sanitizer-tests passando (build limpo com clang-16, sem warnings novos)
  • CI job e2e-wasm: build em container Docker com KLEE real, executa test_wasm_pipeline.sh (3/3) + test_wasm_entrypoint.sh (3/3)
  • Juliet WASM benchmarks: 15 casos (CWE-121/122/124/126/127) executados com map2check --wasm --memtrack --timeout 290, 15/15 FALSE
  • Unit tests: 7/7 passando (ctest --output-on-failure)

Para reproduzir localmente:

docker run --rm -v $(pwd):/workspace -w /workspace -u root ghcr.io/hbgit/map2check-dev:latest bash -c '
  wget -q "https://github.com/WebAssembly/wabt/releases/download/1.0.41/wabt-1.0.41-linux-x64.tar.gz" -O /tmp/w.tgz
  tar xzf /tmp/w.tgz -C /opt && ln -sf /opt/wabt-1.0.41/bin/wasm2c /usr/local/bin/wasm2c
  wget -q "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-33/wasi-sdk-33.0-x86_64-linux.tar.gz" -O /tmp/s.tgz
  tar xzf /tmp/s.tgz -C /opt
  mkdir -p build && cd build
  cmake .. -G Ninja -DLLVM_DIR=/usr/lib/llvm-16/lib/cmake/llvm -DMAP2CHECK_DYNAMIC_LINK=ON
  ninja && ninja install
  mkdir -p ../install/lib/klee && ln -sf /opt/klee/lib/klee/runtime ../install/lib/klee/runtime
  ln -sf /usr/lib/llvm-16/lib/clang ../install/lib/clang
  MAP2CHECK_PATH=$PWD/../install WASI_SDK_PATH=/opt/wasi-sdk-33.0-x86_64-linux bash ../tests/integration/test_wasm_pipeline.sh
  MAP2CHECK_PATH=$PWD/../install WASI_SDK_PATH=/opt/wasi-sdk-33.0-x86_64-linux bash ../tests/integration/test_wasm_entrypoint.sh
'

Changes

Pipeline WASM (modules/frontend/, modules/backend/)

  • wasm_lifter.{hpp,cpp} — orquestra .wasm → wasm2c → clang-16 → LLVM IR
  • map2check.cpp — flag --wasm com detecção automática de entrypoint e fallback de include paths (/opt/wabt-1.0.41/include → /opt/wabt/include → /usr/include)
  • caller.{hpp,cpp} — generateWasmWrapperStatic() cria main() → w2c_*_start; linka WasmRuntimeStubs.bc quando --wasm ativo
  • WasmRuntimeStubs.c — substitui mmap/munmap do WABT por calloc/free compatíveis com KLEE; redireciona wasm_rt_trap → map2check_error
  • MemoryTrackPass.{hpp,cpp} — modo --wasm-mode: intercepta w2c_*_dlmalloc/dlfree, registra offsets no AllocationLog, injeta map2check_wasm_check_access em loads/stores (bounds checking por alocação)
  • Map2CheckLibrary.cpp — suporte a --entry-function configurável
    Build System (CMakeLists.txt, modules/backend/library/lib/CMakeLists.txt)
  • MAP2CHECK_DYNAMIC_LINK=ON — desabilita busca por .a e permite find_library encontrar .so (Z3/STP no Dockerfile.dev só existem como shared)
  • WasmRuntimeStubs restaurado como target ALL quando wasm-rt.h é encontrado
  • Version string: v8.0.0 (LLVM 16, C++17, New PM)
    CI (.github/workflows/ci.yml)
  • Novo job e2e-wasm: build em container Docker com KLEE real, executa ambos os scripts de integração WASM, timeout de 45min
  • Substituição de apt install wabt (1.0.27) por WABT 1.0.41 via GitHub releases nos 3 jobs (build-and-test, static-analysis, sanitizer-tests)
  • Ambos docker run no job E2E executam como root (-u root) para acesso de escrita em /opt/ e /workspace/

Testes (tests/integration/)

  • test_wasm_pipeline.sh — 3 cenários: heap overflow, heap seguro, flag CLI
  • test_wasm_entrypoint.sh — 3 cenários: entrypoint _start, módulos com caracteres hex-encoded, módulos com imports WASI
  • Regex corrigida para aceitar entrypoints _0x5Fstart (hex-encoded)
    Benchmarks Juliet WASM (test-comp2026/simulation/)
  • compile_juliet_wasm.sh — 15 casos (CWE-121/122/124/126/127)
  • wasm_results.csv — 15/15 FALSE com timeout 290s (tempos de 135-179s)

Documentação

  • README.md — instruções de build com Dockerfile.dev e MAP2CHECK_DYNAMIC_LINK
  • docs/migration/1.7-wasm-pipeline.md — status atualizados das sub-etapas 1.7.1-1.7.7
  • .opencode/skills/map2check-sbseg2026/ — backlog, consolidated data e figure inventory atualizados com dados reais

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation (README, SKILL.md, chapters, migration docs)
  • My changes generate no new warnings (build limpo com clang-16 em todos os 4 jobs do CI)
  • I have added tests that prove my feature works (test_wasm_{pipeline,entrypoint}.sh)
  • New and existing unit tests pass locally with my changes (7/7)
  • Any dependent changes have been merged and published in downstream modules

- Dockerfile.dev: add WABT 1.0.41 (wasm2c, wasm2wat), wasi-sdk-33.0,
  lld-16, libc6-dev. Fix GPG key for apt.llvm.org.
- modules/frontend/wasm_lifter.{cpp,hpp}: new WasmLifter module that
  lifts .wasm → LLVM IR via wasm2c + clang-16 pipeline
- modules/frontend/CMakeLists.txt: integrate WasmLifter OBJECT library
- modules/backend/pass/OverflowPass.cpp: fix 3 null pointer dereference
  bugs (calleeFunction nullptr, DbgDeclareInst nullptr) causing segfault
  on ControlFlow benchmarks
- test-comp2026/simulation: add run_controlflow_inside.sh and
  run_controlflow_coverage_inside.sh for TestComp 2026 ControlFlow
- docs/migration/1.7-wasm-pipeline.md: document WASM pipeline phases,
  sessions, and risks
- docs/{map2check_migration_plan,PLAN}.md: update progress and WASM plan
…seg-paper

- Add book-to-skill converter skill for generating book/document skills
- Add map2check-sbseg2026: unified skill merging paper knowledge + project mgmt
  - Core frameworks, 6 chapters, glossary (43 terms), patterns (8), cheatsheet
  - Submission context, backlog, CTA checklist, consolidated data, figure inventory
  - WASM pipeline status and implementation plan
- Remove sbseg-paper (merged into map2check-sbseg2026)
- Add wasm-implementation-plan.md with full roadmap (sub-etapas 1.7.3-1.7.7)
- Update SKILL.md with WASM status, backlog items, topic index entries
- Sec 1: add usage example (listing), fill all citations, compare with competitors
- Sec 2: add competitor comparison at each checkpoint (CPAchecker, Symbiotic, FuSeBMC, ESBMC)
- Sec 3: replace passes table with paragraph focused on techniques, remove isRequired() detail
- Sec 3: remove fig3 (passes) and fig5 (CI/CD), add OpenSSF reference
- Sec 4: rename to 'Análise Experimental', remove fig4 (pizza chart), merge bugs into results paragraph
- Sec 4: remove bugs table, fix CWE mapping (valid-deref → CWE-416, add valid-memsafety)
- Sec 5 (Demonstração): removed entirely per advisor
- Sec 6: split into isolated 'Conclusão'
- Add 4 bib entries: cwe2025, fioraldi2020aflpp, chalupa2021symbiotic, openssf2024
- All 23 citations filled, 0 empty
- ch01: rewritten with usage example, filled references, competitor framework comparison
- ch02: rewritten with competitor comparison at each TACAS checkpoint
- ch03: rewritten with techniques-focused passes paragraph, OpenSSF, no isRequired() detail
- ch04: rewritten as 'Análise Experimental', CWE mapping fixed, bugs merged, WASM more precise
- ch05: removed (Demonstração removida do paper)
- ch06: rewritten as isolated 'Conclusão'
- SKILL.md: updated section count (6→5), chapter index, figure inventory (5→2 figs)
- glossary: +7 new terms (CPAchecker, Z3, CWE-190, Smart Seeds, wasi-sdk, Program Slicing, Portfólio de Solver)
- Updated via pandoc conversion: LaTeX → Markdown → book-to-skill extractor → Mode 4 fold-in
WASM pipeline end-to-end proven: .wasm → wasm2c → LLVM IR → passes → KLEE
250M KLEE instructions executed on lifted WASM code

Changes:
- map2check: --wasm flag + --entry-function flag, accept .wasm extension
- map2check: WasmLifter integration before Caller construction
- caller: generateWasmWrapperStatic() creates main() → wasm bridge
- caller: refactored linkLLVM() to include WasmRuntimeStubs before witness link
- caller: pass --entry-function and --wasm-mode to opt
- Map2CheckLibrary: EntryFunction cl::opt replaces hardcoded "main"
- MemoryTrackPass: MemTrackEntryFunction cl::opt + WasmMode flag
- MemoryTrackPass: instrumentWasmBoundsCheck() injects bounds check on wasm memory loads/stores
- WasmRuntimeStubs.c: malloc-based wasm-rt stubs for KLEE compatibility
- wasm_lifter: fixed entry point detection for w2c_*_0x5Fstart pattern
- CMakeLists.txt: WasmRuntimeStubs.bc compilation with WABT include path
- cmake/FindZ3.cmake: fixed library search paths
- Skill: updated WASM pipeline status (all components ✅)

Approach B (bounds-only): CWE-119/787 coverage, full tracking deferred to post-SBSeg.
Add detailed analysis of why wasm2c static array model prevents
memory safety detection (CWE-401 leak, CWE-416 UAF, CWE-415 double-free)
via Map2Check's current malloc/free-based MemoryTrackPass.

Includes:
- Technical explanation of wasm2c memory model (u8 wasm_memory[])
- Impact table by SV-COMP property
- Three mitigation strategies (A/B/C) with difficulty assessment
- SBSeg MVP recommendation: focus on overflow + reachability
- Empirical validation checklist for next session
Key insight: intercepting w2c_*_dlmalloc by name only works for
C→WASM, not for arbitrary .wasm files from Rust, Go, AssemblyScript.

Changes:
- Add 'Distinção Crítica' section: C→WASM known vs arbitrary WASM
- Add 'O que é linguagem-agnóstico' table: common wasm2c elements
- Add 'O que é viável para o MVP' diagram: bounds + overflow + reach
- Rewrite 'Estratégias' as short/medium/long term horizons
- Update 'Checklist B.4' for bounds checking across languages
- Update 'Riscos' table with language-allocator risk
- Update 'Recomendação MVP' for language-agnostic priorities
- main.tex: ControlFlow coverage-error-call results (138 tasks, score 38)
- main.tex: Juliet WASM validation (6 cases, pipeline confirmed end-to-end)
- .gitignore: add juliet/ clone directory
- juliet_wasm/wasm_results.csv: pipeline results for all 6 WASM cases
- compile_juliet_wasm.sh: script to compile C subset to WASM

Pipeline validated: WASM -> wasm2c -> LLVM IR -> Map2Check -> KLEE.
All 6 cases processed, confirming architectural gap:
static wasm2c arrays are invisible to MemoryTrackPass.
…ackPass

- main.tex: replace 6 mixed cases with 15 real Juliet cases (CWE-121 to 127)
- main.tex: document linear memory bounds gap with research conclusions
- MemoryTrackPass.cpp: bounds checking returns early (wasm2c provides
  native bounds via wasm_rt_trap -> map2check_error already)
- MemoryTrackPass.hpp: add WasmModeActive member for pass constructor
- wasm_results_v2.csv: 15/15 cases pipeline functional, UNKNOWN expected

Key finding: per-buffer overflow cannot be detected at linear memory level
(wasm2c checks 0 to mem->size, not per-allocation bounds). Full memory
safety requires allocator-aware instrumentation (Fase 2, post-SBSeg).
Implements bounds checking by intercepting wasm2c allocator functions
(w2c_*_dlmalloc/w2c_*_dlfree) in MemoryTrackPass and verifying every
load/store against registered allocations.

Changes:
- MemoryTrackPass.hpp: add instrumentWasmMalloc/Free, isWasmAllocator/
  isWasmDeallocator helpers, 3 new FunctionCallee members
- MemoryTrackPass.cpp: intercept dlmalloc/dlfree by name pattern,
  register offsets+size in AllocationLog, verify load/store offsets
- AnalysisModeMemtrack.c: add map2check_wasm_malloc/free/check_access
- Map2CheckFunctions.h: declare new WASM runtime functions
- main.tex: update results (3/3 heap FALSE, 12 stack UNKNOWN)

Results: 3/3 Juliet heap overflow cases (CWE-122, CWE-126) detected
as FALSE with OVERFLOW property violation. Stack cases (CWE-121/124/127)
require allocator-independent tracking (Fase 2, post-SBSeg).
- main.tex: remove --- (use continuous prose), add entrypoint details
  to WASM section (generateWasmWrapperStatic, w2c_*_start translation)
- main.tex: update conclusion with WASM results
- tests/integration/test_wasm_pipeline.sh: heap overflow detection,
  safe heap access, CLI --wasm flag validation
- tests/integration/test_wasm_entrypoint.sh: _start entrypoint
  extraction, special chars in module names, WASI imports
- ci.yml: install wabt via apt, symlink wasm-rt.h to /opt/wabt/include
- CMakeLists.txt (WasmRuntimeStubs): try /opt/wabt-1.0.41, /opt/wabt, then /usr/include
- caller.cpp: check multiple paths for wasm-rt.h include (use stat())
- map2check.cpp: same fallback for WasmLifter wasmRtIncludePath
- Add #include <sys/stat.h> for stat() fallback logic
GuilhermeBn198 and others added 17 commits July 4, 2026 16:00
- SKILL.md: mark WASM items 4-8 completed, add ControlFlow results,
  update WASM pipeline data (bounds, Juliet, CLI, CI), add 4 new
  frameworks (dlmalloc interception, entrypoint translation,
  per-allocation bounds, linear memory gap), expand topic index
- PLAN.md: update all section progress (avg 90%), mark WASM 1.7.1-1.7.7
  completed, set overall progress to 85%, add Iteracao 4 (2026-07-04)
- 1.7-wasm-pipeline.md: set status to Fase 1.7 concluded
- glossary.md: +7 terms (wasm2c, linear memory, dlmalloc, entrypoint
  translation, per-allocation bounds, WasmRuntimeStubs)
- patterns.md: +3 patterns (WASM Lifting, dlmalloc Interception,
  Entrypoint Translation)
- cheatsheet.md: +2 tables (WASM Pipeline Quick Reference,
  Propriedades Detectaveis no WASM, CI Debug)
- Add e2e-wasm job to GitHub Actions (build + run integration tests inside Docker)
- Install WABT/wasi-sdk in CI and symlink KLEE runtime/compiler-rt files
- Add MAP2CHECK_DYNAMIC_LINK CMake option for shared-library builds
- Restore WasmRuntimeStubs as default build target when wasm-rt.h is present
- Fix entrypoint regex in test_wasm_entrypoint.sh for hex-encoded names
- Update Juliet compile script to 15 CWE-121/122/124/126/127 cases
- Add wasm_results_v2.csv: 15/15 FALSE with 290s timeout
- Update skill and migration docs with actual WASM status
…pipeline

- Update WASM Juliet section: 15/15 FALSE (was 3 FALSE + 12 UNKNOWN)
- Add WAsmCases/WasmFalse/WasmTimeout macros
- Add fig6-wasm-pipeline.mmd diagram
- Add nsa2017juliet reference to bibliography
- Add video storyboard for SBSeg SF (5-7 min)
- Update wasm_results.csv with 15 Juliet cases
- Update README with modernized build instructions
- Update migration docs with completed statuses
…EADME

- Replace PNG figures with TikZ (vector, scalable, larger font)
- fig1-timeline.tikz.tex: timeline 2016-2026 with stagnation gap
- fig2-pipeline.tikz.tex: 5-stage verification pipeline in Docker
- Update main.tex to use \input{img/figX-tikz.tex}
- Update img/README with rendering instructions for fig6-wasm-pipeline.mmd
apt ubuntu-22.04 has wabt 1.0.27 whose wasm-rt.h lacks:
- wasm_rt_funcref_table_t (added after 1.0.27)
- bool parameter in wasm_rt_allocate_memory
This caused WasmRuntimeStubs.c compilation failure in CI.

Fix: download WABT 1.0.41 tarball in all 3 CI jobs (build-and-test,
static-analysis, sanitizer-tests) instead of 'apt install wabt'.
…ccess

The map2check-dev image uses non-root user 'map2check' which
cannot write to /opt to install wasi-sdk. Use -u root.
- main.tex: KLEEVersion 3.x -> 3.1
- SKILL.md, patterns.md, cheatsheet.md, chapters/ch03, ch04
- migration docs (1.4, 1.4.3)
- figures (.mmd, .tikz.tex)
- video scripts
- README.md
@hbgit hbgit merged commit 6b3a3ef into develop Jul 6, 2026
9 checks passed
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.

2 participants