tinymux/docs/audit-coverage.md
Stephen Dennis a36fa1d722 docs: Pass 13 residual audit (anti-cool)
Record a disciplined residual pass that avoids another full A–H tour and
skips voluntary D2/D3 re-scout. E3 flatfile re-read is clean; filed #1411
for max-length input_database → .sqlite path overflow; annotated the
#1408 quota/money family. Refresh recommended rotation now that prior
#126x–#1292 residuals are closed.
2026-07-26 19:39:44 +00:00

19 KiB
Raw Permalink Blame History

Audit Coverage Map — TinyMUX 2.14 hardening

Living document. Feature-complete 2.14 work is review-and-fix only. This map tracks where we have looked, when, and what to revisit. We expect to re-audit slices already marked “done” — that is intentional.

Workflow (standing): explore/read → file High/Medium issues → fix PR → Claude cross-review (+ Windows when the path is Win32-only) → merge.

Prefs: server-first; Linux/FreeBSD primary; Windows must not lag; clients/Hydra after server depth is comfortable.


How to use this map

  1. Pick the next slice ID from the queue (or re-queue a prior slice).
  2. Update that rows Last pass / Status when you finish filing issues.
  3. After a fix PR merges, note issue ranges in Notes (optional).
  4. When revisiting, change Status to revisit and bump Last pass.

Status values:

Status Meaning
deep Focused High/Medium pass completed this cycle
partial Touched; known residual or thin coverage
thin Spot-check only or only via related work
deferred Out of current phase by design
revisit Scheduled re-audit of a previously deep slice
backlog Known work, not defect-driven

Slice catalog

Rough line counts are order-of-magnitude (.c/.cpp/.h); they change.

A — Driver / network (server process: netmux)

ID Slice Paths ~Size Last pass Status Notes
A1 Driver bootstrap / COM mux/src/driver.cpp, driver_bridge.cpp, modules.cpp, muxcli.cpp med thin Config basket pull; module load order
A2 GANL adapter / DESC mux/src/ganl_adapter.cpp, interface.h large Pass 12, #1074 deep Restart DESC, DS_NEED_PROTO, IOCP cap, accept path
A3 Net / output / idle mux/src/net.cpp, sitemon.cpp, bsd.cpp large Pass 6 deep #1133#1135 closed (#1139); residual: @restart getpeername fail-open
A4 Telnet NVT mux/src/telnet.cpp med Pass 6 deep #1126/#1128/#1131/#1132 closed (#1139; SB overflow via sbOverflow)
A5 WebSocket (netmux) mux/src/websocket.cpp, websocket_test.* med Pass 3 deep Mask, handshake close, backpressure (#1081#1083)
A6 Signals / restart helpers mux/src/signals.cpp, restart bits in adapter/net med Pass 6 deep #1127/#1129 → #1138; #1130/#1136 → #1139 (cores + dump reaps)
A7 Netaddr / site keys mux/src/netaddr.cpp, tests/netaddr/ small unit green partial Covered by units; logic re-read optional
A8 Slave / stubslave mux/src/slave.cpp, stubslave.cpp, DNS channel in ganl_adapter small #1220 + residual 2026-07-26 deep Framing #1220; residual stubslave write remainder + Win32 DNS queue caps

B — GANL library

ID Slice Paths ~Size Last pass Status Notes
B1 Epoll / select / kqueue / wselect / IOCP mux/ganl/src/*_network_engine.cpp med Pass 12 + residual 2026-07-26 deep #942#947 held; #1290 dual-stack V6ONLY warn on kqueue/IOCP/wselect
B2 IOCP / wselect iocp_*, wselect_* med Pass 2 Windows deep FD_SETSIZE accept leak, IOCP desc cap
B3 OpenSSL transport openssl_transport.cpp med Pass 11 2026-07-26 deep #948/#949 held; #1282 read-BIO cap + cipher list pin
B4 Schannel transport schannel_transport.cpp med Pass 2 + Pass 11 deep #1067#1068/#950#952 held; #1282 handshake/incomplete buffer caps
B5 Connection / buffers connection.cpp, io_buffer, types med Pass 2 context partial Backlog, write posts
B6 GANL tests mux/ganl/tests/ small ongoing partial Expand wselect/IOCP cases over time

C — Engine softcode & evaluation

ID Slice Paths ~Size Last pass Status Notes
C1 Classic eval / AST eval.cpp, ast.cpp, ast_scan.rl large Pass 2 softcode partial elock/lastcreate fixed; full matrix not exhausted
C2 Function builtins mux/modules/engine/functions.cpp, funceval*.cpp, funmath.cpp, funcweb.cpp huge Pass 5 deep #1106#1124 closed (#1121 Highs, #1123 Mediums, #1125 JIT perms); re-rotate by family later
C3 Commands / hooks command.cpp, predicates.cpp, set.cpp (@include) large Pass 12 2026-07-26 deep #1279 @include as includer; #1280 NOEVAL permit/ignore footgun; process_cmdent access-before-handler held
C4 Match / wild match.cpp, wild.cpp med scenario tests partial Live $ capture has scenario; re-read matching
C5 Speech / look / move speech.cpp, look.cpp, move.cpp, create.cpp, … large Pass 8 deep #1181, #1186#1188 open (clone/preserve, moniker HTML, pagecost order, @open HOME)
C6 Boolexp / locks boolexp.cpp med residual C6/G2/F4 deep #839 parse depth; oversize-key NUL (#1294); empty=open by design; AF_IS_LOCK blocks & set

D — JIT / DBT / Lua

ID Slice Paths ~Size Last pass Status Notes
D1 JIT compiler / ECALL jit_compiler.cpp huge Pass 13 deep Guest bounds, setq, watermarks, PIN_ARRAY, fargs
D2 HIR lower / codegen hir_*.cpp large Pass 7 + re-scout 2026-07-26 deep Highs #1143#1146 → #1156; #1149#1150 closed; re-scout filed #1258#1260 (NEG missing codegen, INC/DEC fold UB, max/min/sign/bound int path) — #1258/#1259 closed, #1260 open; #1255/#1256 abs INT64_MIN follow-ups closed
D3 DBT backends dbt*.cpp, dbt_rt/ large Pass 7 + re-scout 2026-07-26 deep Highs #1147#1148/#1152/#1154 closed; Mediums #1151/#1153 closed since the re-scout; no new D3 High. Residual: #1292 interpreter mem_check wrap
D4 Lua module / bytecode lua_mod.cpp, lua_bytecode.*, hir_lower_lua.* med #1309 bring-up deep Gate+loader #1310; correctness #1321; smoke 1428 w/ lua_jit 1; default still off; engage assert → #1317
D5 JIT oracles / fuzzer testcases/tools/jit_diff/, q-reg oracle standing deep tooling Re-run soak regularly, not just on changes

E — Persistence & queue

ID Slice Paths ~Size Last pass Status Notes
E1 SQLite / sqlitedb sqlitedb.cpp, sqlite_backend.cpp large Pass 1, #1073 deep Schema gate, prepare, load paths
E2 Attr cache / write queue attrcache.cpp med Pass 1 + residual 2026-07-26 deep Flush-on-fail leaves queue; #1284 code-cache coalesce + preloaded-miss Get
E3 Flatfile R/W db.cpp, db_rw.cpp large Pass 1 + Pass 13 residual 2026-07-26 deep #806 dbref/lock gates held; color migrate fail-closed; no new High/Medium
E4 Command queue cque.cpp, timer.cpp, cron.cpp large Pass 1, #1080 deep OOM refund, depth, runaway money
E5 Object / player / flags object.cpp, player*.cpp, flags.cpp, powers.cpp large Pass 8 deep #1179#1180 High; #1182#1185 Medium open

F — Modules (loadable)

ID Slice Paths ~Size Last pass Status Notes
F1 comsys_mod mux/modules/comsys/ small Pass 3, 9 deep #1084 locks; Pass 9 dual-path Highs/Mediums with F3
F2 mail_mod mux/modules/mail/ med Pass 2, 9 deep MAIL_DB_LIMIT; Pass 9 body WT #1192 + dual-store #1191
F3 Engine-in-tree comsys/mail engine/comsys.cpp, engine/mail.cpp large Pass 9 deep Dual path vs modules; Highs #1189#1193, Mediums #1194#1199 open
F4 Module ABI / COM engine_com.cpp, modules.h large residual C6/G2/F4 deep IAttributeAccess/IPermissions gated; AtrAddRaw privileged by design; out-param/nValueMax (#1295)

G — Convert / offline tools

ID Slice Paths ~Size Last pass Status Notes
G1 Omega / format convert mux/convert/* huge Pass 1, 3, #1087 deep sprintf class largely closed; re-scan new paths
G2 muxescape / script mux/muxescape/, mux/script/ med residual C6/G2/F4 deep #1296 muxescape 16MiB cap; muxscript -p MarkConnected gate
G3 announce mux/announce/ small thin

H — libmux / platform / unicode

ID Slice Paths ~Size Last pass Status Notes
H1 Alloc / string / time mux/lib/alloc.*, stringutil.*, timeutil.*, alarm.* med residual 2026-07-26 deep #1290 freelist drop-one not wipe-all; alarm/sleep int64 ms clamp
H2 Color / Ragel color_ops.rl, color path med generated-file discipline thin Edit .rl only
H3 UTF-8 / collation utf/, utf8tables.*, unicode_* large deferred Generated tables; deep Unicode later
H4 Platform abstraction platform.cpp, design-platform-interface small thin

I — Hydra proxy

ID Slice Paths ~Size Last pass Status Notes
I1 Session / process manager session_manager.*, process_manager.* med Pass 4 deep #1091#1102 closed (#1103 Highs, #1105 Mediums)
I2 gRPC / gRPC-web grpc_server.*, grpc_web.* med Pass 4 + Pass 10 deep Pass 4: lockout + ListGames/GetGameStatus auth (#1105). Pass 10 residual: #1265 work-queue flood (closed), #1266 unbounded subscribers, #1267 grpc-web SendInput encoding, #1268 uncapped input lines, #1269 GetGameStatus PIDs non-admin
I3 Telnet bridge / stream telnet_bridge.*, telnet_stream.* med Pass 4 deep SB reassembly cap + disconnect (#1101 via #1105)
I4 Proxy WebSocket mux/proxy/websocket.* small Pass 4 deep #1093#1095 closed (#1103 mask/CLOSE; #1105 RSV/control limits)
I5 Accounts / crypto / scrollback account_manager.*, crypto.*, scrollback.* med Pass 4 deep #1091#1092, #1098, #1100 closed (#1103/#1105)
I6 Proxy regression proxy_regression.cpp small Pass 4 + Pass 10 partial Telnet/WS frame cases deep; gRPC/auth/work-queue still absent → #1270

J — Clients (Hydra family)

ID Slice Paths ~Size Last pass Status Notes
J1 Console client client/console/ med deferred
J2 Win32 GUI client/win32gui/ med deferred
J3 Web client client/web/ med deferred
J4 Android Titan client/android/ large build-only notes deferred Resume path untested (status-2.14)
J5 iOS Titan client/ios/ large unit tests in make test partial Parser units only
J6 TinyFugue port client/tf/ med deferred
J7 Shared client bits client/shared/ small deferred

K — Tests, packaging, docs tooling

ID Slice Paths ~Size Last pass Status Notes
K1 Smoke suite testcases/ large every fix PR deep 1325+ TCs; grow when behavior changes
K2 Scenario / stress tests/scenario/, tests/stress/ med opt-in partial wild-capture, site-threshold, jit-perms; make more routine
K3 Unit islands tests/alarm, netaddr, db, libmux small on change partial
K4 Packaging debian/, docker/, dounix.sh, win32/ med thin
K5 Parser research parser/ small deferred Not production runtime
K6 Worldbuilder / tools tools/worldbuilder/ deferred
K7 Generated-file discipline see docs/generated-files.md standing process Never hand-edit outputs

L — Product backlog (not audit defects)

ID Item Status
L1 #1027 in-game archive/restore via SQLite backlog

Pass history (post feature-complete)

Pass When (approx) Focus Issue / PR trail
Pass 1 2026-07 Restart DESC, SQLite durability, queue, JIT host edge, conf ints, convert encode #1039#1061 → PR #1062
Pass 2 2026-07 Softcode, mail_mod, Windows IOCP/wselect, Schannel, JIT residual #1063#1071 → PR #1072; #1073/#1075 schema; #1074/#1076 banner
Pass 3 2026-07 Convert residual, JIT bounds, queue money, WS, comsys_mod, conf live sync #1077#1080 → #1086; #1087/#1088; #1081#1085 → #1089
Pass 4 2026-07 Hydra proxy I1I5 (session, scrollback, WS, auth, process) #1091#1102 filed; Highs → #1103; Mediums → #1105 (complete)
Pass 5 2026-07 Softcode C2 function builtins + JIT ECALL perms Highs #1106#1110 → #1121; Mediums #1111#1119/#1122 → #1123; #1124 JIT check_access → #1125
Pass 6 2026-07 A3 net/output + A4 telnet NVT + A6 signals/restart #1126#1136 filed; #1127/#1129 → #1138; rest → #1139 (complete)
Pass 7 2026-07 D2 HIR + D3 DBT Highs #1143#1148 → #1156; Mediums #1149#1153 residual; also JIT float/ifelse Highs #1157/#1159 closed separately
Pass 8 2026-07 E5 object/player/flags/powers + C5 speech/look/move/create Highs #1179#1181; Mediums #1182#1188 closed in follow-ups
Pass 9 2026-07 F3 engine comsys/mail vs F1/F2 modules Highs #1189#1193; Mediums #1194#1199 largely fixed in follow-up PRs
Pass 10 2026-07-26 I2 gRPC residual + I6 regression gaps Filed #1265#1270 (work-queue flood, subscriber cap, grpc-web encoding, input length, GetGameStatus PIDs, regression gap). No new unauth RCE; Pass 4 auth gates held.
Pass 7 re-scout 2026-07-26 D2 HIR + D3 DBT residual No new D3 Highs; D2 filed #1258 (HIR_NEG no codegen), #1259 (INC/DEC fold UB), #1260 (max/min/sign/bound int path). Left #1151/#1153 to existing owners (both since closed).
Pass B1/H1 residual 2026-07-26 engines + alloc/alarm #1290 freelist, alarm ms, dual-stack warn
Pass D4 residual 2026-07-26 lua_mod bridges #1287 mux.pennies/iswizard/isconnected match softcode perms; string.dump removed
Pass 11 2026-07-26 B3 OpenSSL + B4 Schannel residual #1282 wire-buffer caps + OpenSSL cipher pin; prior #948#952/#1067#1068 still held
Pass E2 residual 2026-07-26 attrcache write queue #1284 code-cache coalesce by source_hash; preloaded miss no longer re-Gets
Pass 13 residual 2026-07-26 Anti-cool: E3 re-read, ltoa/quota family, conf path builders #1411 .sqlite path overflow on max input_database; #1408 family annotated (pay_quota/money); E3 → deep. See docs/survey-residual-pass13-2026-07.md. No D* dive.

Also useful historical surveys (pre-hardening-month):
docs/survey-*-pass-2026-06.md, docs/survey-ganl-networking.md, docs/survey-queue.md, etc.


Revisit is expected. Suggested order balances new surface with re-sweeps. 2026-07-26: prior “Now/Then” rows (#1260#1270, #1280, #1292, #1275) are closed; do not re-queue them as open defects.

Next Slice(s) Why
Now Fix #1411 path helper; resolve #1408 clamp design Fresh Pass 13 Medium + documented family
Then Land free PRs: #1397 Lua engage; dual-review #1405 races Higher ROI than inventing Pass 14
Then #1407 softlib blob (MacBook) + close #1402 when host+guest done LLP64/justify family
Later K2 scenario defaults; F3 dual-path leftovers if any remain open Still not D3
Pass 14+ J* clients by platform After server/proxy confidence
Anytime D5 jit_diff soak + corpus gaps (#1160); #1247 when kagura free Continuous / claimed

When a pass is “empty” (no High/Medium), still record the pass and Status=deep with date — that prevents false “never looked” later.


Review lenses (apply every slice)

Use the same questions so re-audits stay consistent:

  1. Bounds — lengths, indexes, guest/host, stack buffers, sprintf vs snprintf
  2. Lifetime cycle — alloc/free, COM refs, DESC/ws, queue entries, SQLite pins
  3. Permissions — executor vs thing, locks, unfindable, module vs engine
  4. Failure paths — OOM, partial init, reject/close, refund/quota
  5. Config sync — mudconf vs g_dc, boot-only knobs
  6. Platform — Win32 vs POSIX, FD limits, TLS stack differences
  7. Generated files — source + regen present (docs/generated-files.md)

Standing verification (every fix PR)

From docs/status-2.14.md and practice:

  • make install (or Windows netmux.sln when needed)
  • make test (smoke 1319, ganl, netaddr, JIT oracle, iOS units if Darwin)
  • Opt-in: make test-scenario, testcases/tools/jit_diff/soak.sh
  • Windows: Schannel/IOCP/wselect when the slice is Win32-heavy

Changelog (map document)

Date Change
2026-07-24 Initial map after Passes 13; open defects cleared except #1027
2026-07-24 Pass 4 Hydra filed #1091#1102; I* slice status updated
2026-07-25 Pass 4 Highs #1091#1094 merged (#1103); I4/I5/I6 + rotation updated
2026-07-25 Pass 4 Mediums #1095#1102 merged (#1105); Pass 4 complete; rotation → Pass 5 C2
2026-07-25 Pass 5 complete (#1121/#1123/#1125); C2 deep; rotation → Pass 6 A3+A4+A6
2026-07-25 Pass 6 A3+A4+A6 filed #1126#1136; rotation → Fix Pass 6
2026-07-25 Pass 6 complete (#1138 crash/core, #1139 Highs+Mediums); rotation → Pass 7 D2+D3
2026-07-25 Pass 7 Highs closed (#1156); Mediums #1149#1153 residual; D2/D3 deep
2026-07-25 Pass 8 E5+C5 filed #1179#1188; E5/C5 deep; rotation → Pass 9 F3 (or Fix Pass 8 Highs)
2026-07-25 Pass 9 F3/F1/F2 filed #1189#1199; dual-path deep; rotation → Fix Highs (Pass 8/9)
2026-07-25 Residual scout C6+G2+F4 deep; #1294#1296 boolexp NUL, COM guards, muxescape/muxscript
2026-07-26 Pass A8 residual: stubslave parent write remainder + Win32 DNS queue caps; A8 → deep
2026-07-26 Pass 10 I2+I6 residual scout; filed #1265#1270; I2 deep, I6 still partial (test gap)
2026-07-26 Pass 12 C3: @include executor fix #1279; NOEVAL hook issue #1280; C3 → deep
2026-07-26 Pass E2 residual: code-cache write coalesce + preloaded-miss path #1284; E2 → deep
2026-07-26 Pass B1/H1 residual: freelist + alarm + dual-stack #1290; B1/H1 → deep
2026-07-26 Pass D4 residual: Lua bridge Examinable gates + string.dump #1287; D4 → deep
2026-07-26 Pass 11 B3/B4: TLS wire-buffer caps + OpenSSL cipher pin #1282; B3 deep
2026-07-26 Pass 13 residual (anti-cool): E3 re-read deep; #1411 path overflow; #1408 family note; rotation table refreshed (old #126x#1292 closed)

Update this table when the map structure changes.