From efe58242e0a088991eaec941dab60cc3e54a3362 Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Tue, 31 Mar 2026 20:10:00 -0400 Subject: [PATCH] wine: all 5 MOADs CLEAN (wine-0001 pre-existing); wireguard-go: all 5 MOADs CLEAN Wine scan: hot paths use hash tables (module lookup), red-black trees (font families, shader cache), binary search (registry), bounded lists (FBO<=64, sampler<=16, MUI<=8). wine-0001 covers loader dependency dedup. No additional CWE-407 defects. MOADs 0002-0005 CLEAN: loader_section is by design, no request-scoped TLS leakage, kerberos logs only auth_data pointer (not value), all caches protected by critical sections. WireGuard-go scan: peers.keyMap is hash map O(1), AllowedIPs is radix trie O(32). Private key and PSK are never logged (only "Updating X" labels). Device struct has per-sub-struct sync.RWMutex with no thundering herd patterns. MOADs 0002-0005 CLEAN: well-decomposed Device struct, no goroutine-local leakage, proper sync. --- defects/wine/patch/CLEAN.md | 99 +++++++++++++++++++++++++++++ defects/wireguard-go/patch/CLEAN.md | 87 +++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 defects/wine/patch/CLEAN.md create mode 100644 defects/wireguard-go/patch/CLEAN.md diff --git a/defects/wine/patch/CLEAN.md b/defects/wine/patch/CLEAN.md new file mode 100644 index 000000000..8d1e8e7e5 --- /dev/null +++ b/defects/wine/patch/CLEAN.md @@ -0,0 +1,99 @@ +CLEAN — Wine (wine-mirror/wine) — all 5 MOADs scanned 2026-03-31 + +Repository: https://gitlab.winehq.org/wine/wine +Mirror: https://github.com/wine-mirror/wine +Version: HEAD (depth=1 clone) +Language: C +Size: 12,147 files + +Note: wine-0001 (UNDF-2026-000000886) covers MOAD-0001 loader dependency dedup +in dlls/ntdll/loader.c. This marker covers the remaining 4 MOADs plus additional +MOAD-0001 coverage confirming no other hot-path O(N^2) defects beyond wine-0001. + +## MOAD-0001 (CWE-407): wine-0001 filed; additional sites CLEAN + +Hot paths scanned: + +- dlls/ntdll/loader.c: find_basename_module uses hash_table (HASH_MAP_SIZE buckets), + find_named_export uses binary search (find_name_in_exports), loader dependency + dedup covered by wine-0001. + +- server/registry.c: find_subkey and find_value both use binary search on sorted + arrays. O(log N) per registry key/value lookup. CLEAN. + +- dlls/win32u/class.c: find_class uses LIST_FOR_EACH_ENTRY on class_list. The list + contains ~13 builtin classes plus app-registered classes. Called once per + CreateWindow, not in a loop over windows. In practice N < 50. The linear scan + is bounded and not O(N^2). CLEAN. + +- dlls/win32u/font.c: find_family_from_name and find_family_from_any_name both use + wine_rb_get (red-black tree). find_cached_gdi_font scans gdi_font_list with hash + precheck (fontcmp exits early on hash mismatch) — O(N) per CreateFont but not + O(N^2). get_gdi_font_subst called in add_gdi_font_subst at startup only (not + runtime hot path). CLEAN. + +- dlls/wined3d/glsl_shader.c: shader program cache uses wine_rb_tree (O(log N)), + FFP vertex/fragment shader caches use wine_rb_tree. shader_glsl_find_sampler + is O(S) where S = sampler count, bounded by D3D limits (S <= 16). CLEAN. + +- dlls/wined3d/context_gl.c: FBO cache is LIST_FOR_EACH_ENTRY capped at + WINED3D_MAX_FBO_ENTRIES=64. Bounded, not O(N^2). CLEAN. + +- dlls/kernelbase/registry.c: MUI cache is LIST_FOR_EACH_ENTRY capped at + REG_MUI_CACHE_SIZE=8. CLEAN. + +- dlls/secur32/secur32.c: security package table LIST_FOR_EACH_ENTRY is O(P) + where P = number of loaded SSP packages (typically < 10). Called per + QuerySecurityPackage, not per-request. CLEAN. + +## MOAD-0002 (Intertangle): NOTED, architectural + +dlls/ntdll/loader.c: loader_section is a single global RTL_CRITICAL_SECTION +serializing all PE loader operations (LoadLibrary, FreeLibrary, DllMain calls). +This creates a global bottleneck but is mandated by the Windows PE loader +specification — simultaneous DLL loads from multiple threads must be serialized to +prevent dependency race conditions. This is architectural constraint, not a novel +defect. + +dlls/win32u: user_lock() serializes all USER32 object operations. Same pattern, +same justification (Windows USER32 is single-threaded by design). + +No god-object coupling between independent subsystems (e.g., network + graphics + +audio sharing mutable state) found. Wine DLLs are architecturally isolated. + +## MOAD-0003 (Leaked Context): CLEAN + +NtCurrentTeb() provides per-thread TEB (Thread Environment Block) carrying: +- LastStatusValue, LastErrorValue (per-thread error codes — by design) +- ActivationContextStack (COM/SxS context — by design) +- tls_slots (TLS slots — explicitly managed by app) + +These are per-thread, not request-scoped identity carriers. No cross-request +ThreadLocal leakage pattern found. + +dlls/kernelbase/locale.c uses NtCurrentTeb() for locale info — Windows API +design, not a leaked context defect. + +## MOAD-0004 (Logged Secret): CLEAN + +dlls/kerberos/krb5_ap.c: +- kerberos_SpAcquireCredentialsHandle TRACE logs auth_data as %p (pointer only, + not contents). Password extracted via get_password_unixcp() and passed to + init_creds() but never logged. +- init_creds() in unixlib.c calls krb5_get_init_creds_password() with password + but logs only "success" on completion. + +dlls/secur32/wrapper.c: AcquireCredentialsHandle logs pAuthData as %p (pointer). +No password/credential value appears in any TRACE/WARN/ERR call. + +## MOAD-0005 (Thundering Herd): CLEAN + +dlls/ntdll/loader.c: all module cache access (cached_modref) occurs under +loader_section critical section. No unsynchronized check-then-act. + +dlls/win32u: all class_list access under user_lock(). No double-check locking. + +dlls/wined3d: GL context operations are per-thread (each thread has its own +context_gl). No shared cache without synchronization found. + +server/ (wineserver): single-threaded event loop — no concurrent cache misses. diff --git a/defects/wireguard-go/patch/CLEAN.md b/defects/wireguard-go/patch/CLEAN.md new file mode 100644 index 000000000..3f5680c42 --- /dev/null +++ b/defects/wireguard-go/patch/CLEAN.md @@ -0,0 +1,87 @@ +CLEAN — WireGuard/wireguard-go — all 5 MOADs scanned 2026-03-31 + +Repository: https://github.com/WireGuard/wireguard-go +Version: HEAD (depth=1 clone) +Language: Go +Size: ~40 Go source files + +Note: wireguard-tools (C userspace tools) was scanned previously and is CLEAN. +This entry covers wireguard-go (pure Go userspace WireGuard implementation). + +## MOAD-0001 (CWE-407): CLEAN + +Hot paths scanned: + +device/device.go: peer lookup uses peers.keyMap (map[NoisePublicKey]*Peer) — O(1) +hash map per peer lookup. No linear scan of peer list in the packet path. + +device/allowedips.go: AllowedIPs uses a radix trie (256-ary, one level per bit). +IP-to-peer lookup is O(32) for IPv4 or O(128) for IPv6 — bounded and constant. +Not a linear scan. CLEAN. + +device/receive.go: ReceiveIPv4/ReceiveIPv6 batch processing loops are O(batch_size) +with no inner membership scans. Handshake queue processing dispatches by index table +(IndexTable, which is map[uint32]*indexTableEntry). CLEAN. + +device/uapi.go: UAPI config parsing scans device.peers.keyMap for peer lookup — +O(P) configuration-time only, not per-packet. P = number of peers (bounded by +WireGuard protocol limits, typically < 10,000). CLEAN. + +## MOAD-0002 (Intertangle): CLEAN + +Device struct (device/device.go) is well-decomposed into named sub-structs: +state (atomic + Mutex), net (RWMutex + bind/port/fwmark), staticIdentity +(RWMutex + privateKey/publicKey), peers (RWMutex + keyMap), rate, pool, queue, +tun. Each sub-struct owns its own mutex. + +No god-object pattern: cryptographic handshake (noise-protocol.go) is isolated +from packet routing (allowedips.go), session key management (keypair.go), and +rate limiting (ratelimiter/). Subsystems communicate through channel queues +(device.queue.handshake, device.queue.encryption, device.queue.decryption), +not shared mutable global state. + +## MOAD-0003 (Leaked Context): CLEAN + +No goroutine-local state beyond sync.Pool buffers (byteBufferPool). Go does not +have goroutine-local storage; the design relies on explicit context propagation. + +context.Context is used only in ipc/namedpipe (Windows IPC) and tun/netstack +(virtual network stack) — both pass context explicitly, not via goroutine-local +storage. No request-scoped identity leaked across goroutine boundaries. + +## MOAD-0004 (Logged Secret): CLEAN + +device/uapi.go: +- private_key handling: device.log.Verbosef("UAPI: Updating private key") — logs + label only, never logs the key value. The key bytes come from sk.FromMaybeZeroHex(value) + and are passed to device.SetPrivateKey(sk). Value is never interpolated into + any log call. CLEAN. +- preshared_key handling: device.log.Verbosef("%v - UAPI: Updating preshared key", peer.Peer) + — logs peer identifier and label only. Key bytes from peer.handshake.presharedKey.FromHex(value) + are never logged. CLEAN. + +device/noise-protocol.go: no log calls that reference key material. Handshake state +transitions logged as enum values (ConsumeMessageInitiation: handshake replay, flood). +No Curve25519 private key, ChaCha20-Poly1305 session key, or PSK ever interpolated +into log output. + +CRITICAL CHECK PASSED: no private key or pre-shared key logging found anywhere. + +## MOAD-0005 (Thundering Herd): CLEAN + +device/device.go: all peer map access guarded by peers.RWMutex (readers use RLock, +writers use Lock). No check-null-compute-put pattern. + +device/noise-protocol.go: handshake state uses handshake.mutex (sync.RWMutex). +Keypair rotation uses atomic operations (keypairs struct with Next/Current/Previous +protected by sync.RWMutex). + +device/allowedips.go: AllowedIPs mutations protected by mutex (sync.RWMutex at +AllowedIPs struct level). Trie updates hold the write lock throughout. + +device/keypair.go: keypair store uses sync.RWMutex for all access. + +ratelimiter/: uses sync.Mutex for table access, time.Ticker for GC — properly +synchronized. + +No unsynchronized cache get+null+compute+put pattern found in any hot path.