security: add seccomp server presets

Jaime Fournier <jaimef@linbsd.org>

1692077b6f99bcaaf7f0b674e05416149e9fd83e

diff --git a/docs/kimi3-security-recommmendations.md b/docs/kimi3-security-recommmendations.md
index 3fedd7b..4df83ec 100644
--- a/docs/kimi3-security-recommmendations.md
+++ b/docs/kimi3-security-recommmendations.md
@@ -723,6 +723,12 @@ Chez cannot heap-cap a thread; `run-safe-eval` rightly refuses
   audit logs and the release-evidence bundle).
 - **Accept:** per-platform CI smoke for each mechanism; presets used by
   P0-02 worker tests.
+- **Status:** partially complete. The seccomp preset gap is closed for the
+  supported syscall tables: `(std security seccomp)` now exports
+  `http-server-filter`, `dns-server-filter`, and `worker-eval-filter`, and
+  `(std security sandbox)` accepts `'http-server`, `'dns-server`, and
+  `'worker-eval` seccomp specs. Native per-platform CI parity and a dedicated
+  runtime `sandbox-report` entry point remain open.
 
 ### K3-P1-09 — Confused-deputy defenses: capability plans enforced at runtime
 **Serves:** G2. **Effort:** 1 week.
diff --git a/docs/security-reference.md b/docs/security-reference.md
index fd49978..2b838cf 100644
--- a/docs/security-reference.md
+++ b/docs/security-reference.md
@@ -339,7 +339,9 @@ Linux syscall filtering via real BPF bytecode. Generates actual `sock_filter` pr
 - `(seccomp-available?)` -- check kernel support
 - `(make-seccomp-filter default-action: action allowed: syscall-list)` -- create a filter
 - `(seccomp-install! filter)` -- install filter (irreversible)
-- Pre-built filters: `compute-only-filter`, `io-only-filter`, `network-server-filter`
+- Pre-built filters: `compute-only-filter`, `io-only-filter`,
+  `network-server-filter`, `http-server-filter`, `dns-server-filter`,
+  `worker-eval-filter`
 - Actions: `seccomp-kill`, `seccomp-trap`, `seccomp-errno`, `seccomp-log`
 
 BPF program structure: validate architecture, load syscall number, check against allowed list, apply default action for non-matching syscalls.
diff --git a/lib/std/security/sandbox.ss b/lib/std/security/sandbox.ss
index 6bb8677..099f642 100644
--- a/lib/std/security/sandbox.ss
+++ b/lib/std/security/sandbox.ss
@@ -241,8 +241,11 @@
       [(eq? spec 'compute-only) compute-only-filter]
       [(eq? spec 'io-only) io-only-filter]
       [(eq? spec 'network-server) network-server-filter]
+      [(eq? spec 'http-server) http-server-filter]
+      [(eq? spec 'dns-server) dns-server-filter]
+      [(eq? spec 'worker-eval) worker-eval-filter]
       [else (error 'run-safe
-              "invalid seccomp spec; expected #f, 'compute-only, 'io-only, 'network-server, or seccomp-filter"
+              "invalid seccomp spec; expected #f, 'compute-only, 'io-only, 'network-server, 'http-server, 'dns-server, 'worker-eval, or seccomp-filter"
               spec)]))
 
   ;; ========== Seatbelt profile resolution (macOS) ==========
diff --git a/lib/std/security/seccomp.ss b/lib/std/security/seccomp.ss
index 05c0bc9..a8ba4e6 100644
--- a/lib/std/security/seccomp.ss
+++ b/lib/std/security/seccomp.ss
@@ -26,6 +26,9 @@
     ;; Pre-built filters
     compute-only-filter
     network-server-filter
+    http-server-filter
+    dns-server-filter
+    worker-eval-filter
     io-only-filter
     dangerous-syscalls
     safe-blocklist
@@ -506,6 +509,25 @@
       ;; File I/O
       'openat 'newfstatat 'getdents 'access))
 
+  (def http-server-filter network-server-filter)
+
+  (def dns-server-filter
+    (make-seccomp-filter seccomp-kill
+      ;; Compute basics
+      'read 'write 'close 'fstat 'mmap 'mprotect
+      'munmap 'brk 'rt_sigaction 'rt_sigprocmask 'rt_sigreturn
+      'clone 'exit_group 'futex 'nanosleep
+      'getrandom 'arch_prctl 'set_tid_address
+      'set_robust_list 'sched_yield 'sigaltstack
+      'clock_gettime 'prctl 'prlimit64 'rseq 'close_range
+      ;; DNS server/client UDP and TCP fallback using known syscall-table names
+      'socket 'connect 'sendto 'recvfrom
+      'bind 'listen 'accept 'getsockname 'setsockopt
+      'select 'ioctl 'fcntl
+      'epoll_create1 'epoll_ctl 'epoll_wait))
+
+  (def worker-eval-filter compute-only-filter)
+
   (def io-only-filter
     (make-seccomp-filter seccomp-kill
       'read 'write 'close 'fstat 'mmap 'mprotect
diff --git a/tests/test-phase5-os.ss b/tests/test-phase5-os.ss
index d9a2bd2..12d9cf1 100644
--- a/tests/test-phase5-os.ss
+++ b/tests/test-phase5-os.ss
@@ -44,6 +44,15 @@
 (test "seccomp: make network-server filter"
   (seccomp-filter? network-server-filter))
 
+(test "seccomp: make http-server filter"
+  (seccomp-filter? http-server-filter))
+
+(test "seccomp: make dns-server filter"
+  (seccomp-filter? dns-server-filter))
+
+(test "seccomp: make worker-eval filter"
+  (seccomp-filter? worker-eval-filter))
+
 (test "seccomp: make io-only filter"
   (seccomp-filter? io-only-filter))
 
diff --git a/tests/test-seccomp.ss b/tests/test-seccomp.ss
index e3f687e..f1d176e 100644
--- a/tests/test-seccomp.ss
+++ b/tests/test-seccomp.ss
@@ -55,6 +55,18 @@
   (seccomp-filter? network-server-filter)
   #t)
 
+(test "http-server-filter is a filter"
+  (seccomp-filter? http-server-filter)
+  #t)
+
+(test "dns-server-filter is a filter"
+  (seccomp-filter? dns-server-filter)
+  #t)
+
+(test "worker-eval-filter is a filter"
+  (seccomp-filter? worker-eval-filter)
+  #t)
+
 (test "io-only-filter is a filter"
   (seccomp-filter? io-only-filter)
   #t)
@@ -68,6 +80,26 @@
      (length (seccomp-filter-allowed-syscalls compute-only-filter)))
   #t)
 
+(test "http-server-filter includes listener syscalls"
+  (and (memq 'socket (seccomp-filter-allowed-syscalls http-server-filter))
+       (memq 'bind (seccomp-filter-allowed-syscalls http-server-filter))
+       (memq 'listen (seccomp-filter-allowed-syscalls http-server-filter))
+       (memq 'accept (seccomp-filter-allowed-syscalls http-server-filter))
+       #t)
+  #t)
+
+(test "dns-server-filter includes DNS transport syscalls"
+  (and (memq 'socket (seccomp-filter-allowed-syscalls dns-server-filter))
+       (memq 'sendto (seccomp-filter-allowed-syscalls dns-server-filter))
+       (memq 'recvfrom (seccomp-filter-allowed-syscalls dns-server-filter))
+       (memq 'bind (seccomp-filter-allowed-syscalls dns-server-filter))
+       #t)
+  #t)
+
+(test "worker-eval-filter excludes network syscalls"
+  (not (memq 'socket (seccomp-filter-allowed-syscalls worker-eval-filter)))
+  #t)
+
 ;; ========== Availability ==========
 
 (printf "~%-- Availability --~%")