gdb+valgrind: 5-MOAD scan; CLEAN both targets
This commit is contained in:
parent
c13562b619
commit
38b5c504cf
2 changed files with 117 additions and 0 deletions
56
defects/gdb-scan/CLEAN.md
Normal file
56
defects/gdb-scan/CLEAN.md
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# GDB (GNU Debugger) — 5-MOAD Scan
|
||||
|
||||
**Source:** https://github.com/bminor/binutils-gdb (depth=1 snapshot 2026-03-31)
|
||||
**Scan date:** 2026-03-31
|
||||
|
||||
## MOAD-0001 (CWE-407) — CLEAN
|
||||
|
||||
Our scan examined our primary hot paths:
|
||||
|
||||
- `gdb/breakpoint.c` — `build_bpstat_chain()` iterates `all_breakpoints()` with nested
|
||||
`all_bp_locations_at_addr()` using binary search (`std::equal_range`). `update_global_location_list()`
|
||||
sorts `bp_locations` then uses a sorted-scan duplicate-detection algorithm. No O(N^2) inner loops.
|
||||
- `gdb/symtab.c` — Symbol cache uses a hash-bucketed `symbol_cache_slot` array. Block lookup
|
||||
(`block_lookup_symbol`) delegates to a dictionary (hashtable). No linear membership inside outer loop.
|
||||
- `gdb/dwarf2/read.c` — DWARF CU processing uses `gdb::unordered_set` for visited sets throughout.
|
||||
`visited_not_found` / `visited_found` are explicit hash sets.
|
||||
- `gdb/dwarf2/abbrev.h` — Abbrev table stored as `std::unordered_set` with custom hash.
|
||||
- `gdb/dwarf2/cooked-index-shard.c` — `find()` uses `std::equal_range` (binary search) on sorted vector.
|
||||
- `gdb/inline-frame.c` — `inline_states` is a small vector (one entry per active thread).
|
||||
`find_inline_frame_state()` is O(T) where T = thread count, called once per frame unwind.
|
||||
Not a scaling defect in practice.
|
||||
- `gdb/solib-svr4.c` — `glibc_tls_slots` uses `std::find` to locate empty slot on SO load
|
||||
(fill) and locate slot by address on SO unload (erase). This is O(S) per SO load event
|
||||
where S = number of TLS-bearing SOs, giving O(S^2) across startup. With S typically < 100
|
||||
for real programs, this amounts to < 5,000 comparisons total. Severity: NEGLIGIBLE.
|
||||
- `gdb/cp-namespace.c` — `found_symbols` is a `std::map` (ordered by name). Not a vector.
|
||||
- `gdb/ada-lang.c` — Exception dedup uses `std::sort` + `std::unique` (O(N log N)).
|
||||
|
||||
**Verdict: CLEAN.** Our codebase uses hash tables, binary search, and sorted arrays consistently
|
||||
throughout all hot paths. No actionable O(N^2) defects found.
|
||||
|
||||
## MOAD-0002 (Intertangle) — CLEAN
|
||||
|
||||
GDB uses `current_program_space`, `current_inferior()`, and thread globals extensively.
|
||||
This is a known architectural design (single active inferior at a time) with a well-defined
|
||||
execution model, not an accidental coupling. Each command operates on an explicit context.
|
||||
No unintended cross-phase state bleed found.
|
||||
|
||||
## MOAD-0003 (Leaked Context) — CLEAN
|
||||
|
||||
`gdb/complaints.c` uses `thread_local complaint_interceptor*` — this is a controlled,
|
||||
intentional use to redirect diagnostic output during symbol reading. It is scoped to the
|
||||
main UI thread only (`gdb_assert (is_main_thread())` enforces this). Not a request-scoped
|
||||
identity leak.
|
||||
|
||||
## MOAD-0004 (CWE-312 Logged Credentials) — CLEAN
|
||||
|
||||
GDB's RSP (remote serial protocol) in `gdb/remote.c` does not implement authentication.
|
||||
No auth tokens, passwords, or credentials pass through the GDB remote protocol layer.
|
||||
`remote_debug` output logs protocol packets but none contain credentials.
|
||||
|
||||
## MOAD-0005 (Thundering Herd) — CLEAN / NOT APPLICABLE
|
||||
|
||||
GDB is architecturally single-threaded for all analysis operations. The UI thread is the
|
||||
only thread that accesses symbol tables, breakpoints, and inferior state. No concurrent
|
||||
cache access patterns possible. MOAD-0005 does not apply.
|
||||
61
defects/valgrind-scan/CLEAN.md
Normal file
61
defects/valgrind-scan/CLEAN.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Valgrind — 5-MOAD Scan
|
||||
|
||||
**Source:** https://gitlab.com/fbrausse/valgrind (depth=1 snapshot 2026-03-31)
|
||||
**Scan date:** 2026-03-31
|
||||
|
||||
## MOAD-0001 (CWE-407) — CLEAN
|
||||
|
||||
Our scan examined the core Valgrind infrastructure:
|
||||
|
||||
- `coregrind/m_debuginfo/readelf.c` — Symbol dedup uses `VG_(OSetGen_Lookup)` (AVL tree,
|
||||
O(log N) per lookup). Symbol processing loop at lines 828 and 964 does not contain inner
|
||||
linear membership scans.
|
||||
- `coregrind/m_debuginfo/storage.c` — Symbol finalization (`ML_(canonicaliseTables)`) sorts
|
||||
symbols first, then merges adjacent duplicates in a single O(N) pass. No O(N^2).
|
||||
- `coregrind/m_debuginfo/debuginfo.c` — `find_or_create_DebugInfo_for()` does a linear scan
|
||||
of `debugInfo_list` (a linked list of loaded shared objects). Called O(S) times during
|
||||
program startup, giving O(S^2) string comparisons. With S typically < 200 shared objects,
|
||||
this is < 20,000 string comparisons — startup noise only. Severity: NEGLIGIBLE.
|
||||
- `coregrind/m_debuginfo/tytypes.c` — Type deduplication uses simple iteration over bounded
|
||||
arrays (small field counts). No unbounded O(N^2) pattern.
|
||||
- `coregrind/m_errormgr.c` — `VG_(maybe_record_error)` walks the `errors` linked list to
|
||||
find duplicate error contexts. This is O(E) per new error event, giving O(E^2) overall.
|
||||
However, Valgrind caps distinct errors at `M_COLLECT_NO_ERRORS_AFTER_SHOWN=1000`, bounding
|
||||
the list to at most 1000 entries. This cap is itself a workaround for the quadratic behavior.
|
||||
Severity: LOW (bounded by design).
|
||||
- `coregrind/m_mallocfree.c` — Freelist scan has an explicit bound of 100 iterations per
|
||||
freelist level (`nsearches_this_level >= 100` guard). The code itself documents this
|
||||
and proposes a shortcut array as a fix. The guard prevents worst-case behavior.
|
||||
- `helgrind/hg_main.c` — LAOG (Lock Acquisition Order Graph) DFS uses `VG_(newFM)` (AVL tree)
|
||||
for visited set, making path-finding O(V log V). Lock sets use sorted WordSet arrays.
|
||||
- `memcheck/mc_leakcheck.c` — `find_chunk_for()` uses binary search on sorted chunks array.
|
||||
- `memcheck/mc_main.c` — AuxMap uses a 2-level structure (L1 self-organizing array + L2 AVL tree).
|
||||
|
||||
**Verdict: CLEAN.** Core data structures use AVL trees (OSet/FM family), binary search, and
|
||||
bounded arrays. No actionable high-severity O(N^2) defects found.
|
||||
|
||||
## MOAD-0002 (Intertangle) — CLEAN
|
||||
|
||||
Valgrind's `debugInfo_list`, `suppressions`, and `errors` are global state by architectural
|
||||
necessity — Valgrind is a tool framework that instruments a single target process. This is
|
||||
intentional coupling, not accidental Intertangle. No unintended cross-tool state sharing found.
|
||||
|
||||
## MOAD-0003 (Leaked Context) — CLEAN
|
||||
|
||||
Valgrind does not use POSIX threads for its own analysis. Thread identity for the analyzed
|
||||
program is carried explicitly via `ThreadId tid` parameters throughout. No `pthread_getspecific`
|
||||
or equivalent thread-local carrier used for request-scoped identity.
|
||||
|
||||
## MOAD-0004 (CWE-312 Logged Credentials) — CLEAN
|
||||
|
||||
The `--vgdb` protocol does not implement authentication. `VG_(debugLog)` output is diagnostic
|
||||
only. No HTTP headers, auth tokens, API keys, or credentials flow through Valgrind's logging
|
||||
path. Scan of all `.c` files for `password`, `passwd`, `credential`, `secret` found only
|
||||
test files and syscall wrappers (for inspecting `keyctl()` and similar syscalls as data, not
|
||||
as log subjects).
|
||||
|
||||
## MOAD-0005 (Thundering Herd) — CLEAN / NOT APPLICABLE
|
||||
|
||||
Valgrind runs in a single-threaded coregrind loop that serializes all analysis. All tool
|
||||
callbacks (`tool_eq_Error`, `tool_update_extra`, etc.) are called from one execution context.
|
||||
No concurrent cache access patterns possible. MOAD-0005 does not apply.
|
||||
Loading…
Add table
Add a link
Reference in a new issue