Add Slang migration assessment and WASM implementation gap analysis
ober
7b171ec13cfb410fda158bbd82307d9692020738
new file mode 100644 --- /dev/null +++ b/slack.md @@ -0,0 +1,98 @@ +# Slang Migration Assessment — jerboa-secmon + +## Slang Changes (Past 2 Days) + +Two commits landed in `~/jerboa/`: + +| Commit | Date | What | +|--------|------|------| +| `775ce22` | Mar 30 | **Add Slang**: compiler (`compiler.sls`), preamble (`preamble.sls`), linker (`link.sls`), spec (`slang.md`), 127 tests | +| `02e462c` | Mar 31 | **Slang→WASM**: WASM values/GC/runtime/closures, full WASM codegen (`wasm-target.sls`), 140 tests | + +Slang is a **restricted subset of Jerboa** — it validates source against a safe subset, injects a security preamble (Capsicum/seccomp/Landlock), and compiles to either a hardened static binary or WASM bytecode. Every Slang program is valid Jerboa, but only ~60% of Jerboa constructs are allowed. + +--- + +## How Much of jerboa-secmon Can Be Rewritten in Slang? + +**~63% by line count** — but the breakdown matters far more than the number. + +### What CAN be rewritten in Slang (~3,525 lines, 20 modules) + +These modules have no FFI, no shell access, no user macros — they're pure logic: + +| Component | Lines | Notes | +|-----------|-------|-------| +| All 16 monitor modules | ~1,983 | Pure pattern-matching on platform data | +| `monitor/events.sls` | 65 | Event struct + JSON serialization | +| `monitor/suspicious.sls` | 193 | Hardcoded detection lists | +| `server/protocol.sls` | 207 | Bytevector pack/unpack | +| `storage/store.sls` | 360 | SQL queries (declare DB as resource) | +| `buffer/ring.sls` | 88 | Refactor mutex → channels | +| `platform/provider.sls` | 42 | Pure interface/trait definitions | +| `bin/analyze.ss` | 384 | **Best candidate** — no crypto, no network, no FFI | +| `config.sls` | 62 | Needs `obfstr` macro removed (Slang forbids user macros) | + +**Standout candidate: `analyze.ss`** — This is a perfect Slang standalone binary. It only reads SQLite, runs detection rules, outputs JSON. Compile it with Slang and you get a self-sandboxing analysis tool with Capsicum/seccomp enforced at the kernel level. + +### What CANNOT be rewritten in Slang (~2,094 lines, 15 modules) + +Slang forbids `foreign-procedure`/`c-lambda` and `system`/`process-create`. These all use one or both: + +| Component | Lines | Blocker | +|-----------|-------|---------| +| `crypto/ecies.sls` + `psk.sls` + `keys.sls` | 306 | `foreign-procedure` (X25519, HKDF, AEAD) | +| `stealth/anti-debug.sls` | 193 | `foreign-procedure` (ptrace) | +| `stealth/integrity.sls` | 189 | `foreign-procedure` (readlink, mmap) | +| `stealth/masquerade.sls` | 49 | `foreign-procedure` (setproctitle) | +| `stealth/env-sanitize.sls` | 27 | `foreign-procedure` (unsetenv) | +| `stealth/obfuscate.sls` | 29 | `define-syntax` (user macro, forbidden) | +| `server/listener.sls` | 192 | `foreign-procedure` (socket/bind/listen/accept) | +| `platform/freebsd.sls` + `linux.sls` | 452 | Shell commands + FFI | +| `bin/agent.ss` | 114 | Orchestrates all of the above | +| `bin/collector.ss` | 420 | Socket FFI + crypto | +| `bin/keygen.ss` | 46 | Crypto FFI | + +--- + +## The Architectural Constraint + +The monitors are pure logic (rewritable), but they depend on data from the platform providers (FFI/shell — not rewritable). In Slang you can't call `foreign-procedure` or run `ps`. This means: + +**You'd need a two-layer architecture:** +- **Non-Slang shim** (regular Jerboa): Collects data via platform provider, feeds it to the detection engine +- **Slang detection engine**: Receives structured data, runs pattern matching, emits events + +This is actually how the WASM target is intended to be used: the host (regular Jerboa/Rust) does I/O, passes data into the sandboxed Slang/WASM module, gets results back. + +--- + +## Recommended Slang Migration Strategy + +**Immediate wins (low risk):** + +1. **`analyze.ss` → standalone Slang binary** — complete self-contained rewrite, no dependencies on FFI. Gets you Capsicum/seccomp hardening on the analysis tool for free. + +2. **DNS + log parsers as WASM modules** — `monitor/dns.sls`, `monitor/auth.sls`, `monitor/selinux.sls` all parse text/bytes from untrusted sources. Running these as wasmi-sandboxed WASM modules (using the new `wasm-target.sls`) isolates malicious input from the agent process. + +3. **Detection engine as a Slang library** — Extract the pattern-matching core from all 16 monitors into a Slang module. The non-Slang platform layer feeds it `ProcessInfo`/`ConnectionInfo` records; the Slang layer does all the suspicious-pattern evaluation. + +**Keep in regular Jerboa (indefinitely):** +- All crypto (ECIES, PSK, key generation) +- All stealth (anti-debug, masquerade, integrity) +- TCP server + socket handling +- Platform data collection (ps, /proc) + +--- + +## Summary + +| Category | Lines | % | Slang-compatible? | +|----------|-------|---|-------------------| +| Detection logic (16 monitors + events + patterns) | ~2,183 | 39% | **Yes** | +| Protocol + storage + buffer + config + analyze | ~1,342 | 24% | **Yes** (minor refactoring) | +| Crypto (3 modules) | 306 | 5% | No — FFI | +| Stealth (6 modules) | 522 | 9% | No — FFI + user macros | +| Platform + server + binaries | ~1,266 | 23% | No — FFI + shell | + +**~63%** of the codebase is Slang-compatible by structure. The irreducible 37% (crypto, stealth, raw I/O) must remain regular Jerboa — and that's intentional: those modules exist *because* they need to escape the sandbox. new file mode 100644 --- /dev/null +++ b/wasm-gaps.md @@ -0,0 +1,81 @@ +# WASM Implementation Gaps — Slang-to-WASM for jerboa-secmon + +Gaps are in the Jerboa implementation, not inherent WASM limitations. + +--- + +## Critical (block real use) + +**1. Host imports are stubs with no Rust backing** +`wasm-target.sls:57-96` declares WASI + DNS-specific imports (`fd_read`, `recv_packet`, +`cdb_open`, etc.) but there is no implementation in `jerboa-native-rs/src/`. The WASM +module instantiates but fails on the first import call. + +**2. `map`/`filter`/`fold-left` have no lowering rule** +`compiler.sls:386` permits them; `wasm-target.sls:432` passes unknown calls through to an +`[else ...]` fallback. No pre-compiled WASM runtime implements them. Any Slang code using +`map` or `filter` fails at runtime. + +**3. UTF-8 string-length counts bytes, not codepoints** +`scheme-runtime.sls:206` has an inline `TODO: proper UTF-8 codepoint counting`. DNS labels +with non-ASCII characters will have wrong lengths. + +--- + +## High-Priority (limit features) + +**4. Result type operators not lowered** +`->?`, `and-then`, `map-ok`, `map-err`, `try-result` are on the allowed list +(`compiler.sls:334-336`) but have no lowering rules and no WASM runtime implementations. + +**5. `quasiquote`/`unquote` not handled** +Only `quote` is lowered (`wasm-target.sls:428-429`). Quasiquote falls through to the +function-call handler, which fails. + +**6. Variadic `(lambda (x . rest) ...)` not handled** +Closure lifting in `closure.sls` doesn't special-case rest parameters — only fixed-arity +lambdas work. + +--- + +## Medium (no immediate blocker) + +**7. Exception handling tags defined but not lowered** +`runtime.sls:59-65` has the data structures; no `throw`/`catch` encoding in +`wasm-target.sls`. Use `guard` instead. + +**8. Bulk memory ops unused** +`memory.fill`/`memory.copy` are documented in `codegen.sls:55-58` but `wasm-target.sls` +emits loop equivalents instead. Performance cost, not correctness. + +**9. No tail call lowering** +`return-call` exists in the runtime but is never emitted, so recursive Slang functions in +WASM will stack-overflow. Slang's recursion depth limit (default: 1000) is enforced by the +compiler, which partially mitigates this. + +--- + +## What's Actually an Inherent WASM Limitation + +Very little, because Slang's restrictions already align with WASM's constraints: +- No `call/cc` — WASM has no delimited continuations, but Slang forbids it anyway +- Linear memory only, no GC — true limitation, but the bump allocator + arena reset covers + typical monitoring workloads +- Bounded call stack — Slang's recursion depth limit already enforces this + +--- + +## Practical Impact on the secmon Port + +The three monitoring candidates for WASM modules (`monitor/dns.sls`, `monitor/auth.sls`, +`monitor/selinux.sls`): + +| Gap | dns.sls | auth.sls | selinux.sls | +|-----|---------|----------|-------------| +| No host imports | **Blocks** (needs recv_packet) | Minor (reads pre-opened FD) | Minor | +| No `map`/`filter` lowering | **Blocks** | **Blocks** | **Blocks** | +| UTF-8 string-length | **Blocks** (DNS labels) | Minor | Minor | +| No result type ops | Moderate | Moderate | Moderate | + +The host import layer and higher-order function lowering are the two fixes needed before the +WASM path is usable. Both are Jerboa implementation work, not fundamental WASM limitations.