runtime: fix the memory-leak + write-corruption pair in el_runtime.c #64

Merged
will.anderson merged 1 commits from hotfix/el-runtime-leak-and-persist into main 2026-07-13 21:23:39 +00:00
Owner

The complete arena-lifetime fix pair, verified live for 5h against the recovered production snapshot. Half 1 (leak): jb_finish() arena-tracking for all JsonBuf returns + per-tick el_arena_push/pop support. Half 2 (corruption, from Tim's container findings / docs PR #4): 39 stored-field sites el_strdup -> el_strdup_persist + engram_load double-free fix. The two must ship together — per-tick reclamation widens the UAF window without the persist fix. Field-integrity write test passes; June corruption fingerprint does not reproduce. engram/dist binary rebuilt from this runtime.

The complete arena-lifetime fix pair, verified live for 5h against the recovered production snapshot. Half 1 (leak): jb_finish() arena-tracking for all JsonBuf returns + per-tick el_arena_push/pop support. Half 2 (corruption, from Tim's container findings / docs PR #4): 39 stored-field sites el_strdup -> el_strdup_persist + engram_load double-free fix. The two must ship together — per-tick reclamation widens the UAF window without the persist fix. Field-integrity write test passes; June corruption fingerprint does not reproduce. engram/dist binary rebuilt from this runtime.
will.anderson added 1 commit 2026-07-13 21:22:44 +00:00
runtime: fix the memory leak + write-corruption pair in el_runtime.c
El SDK Release / build-and-release (pull_request) Failing after 11m58s
f78da81aa4
Two independent investigations, one runtime, complementary halves:

1. Leak (Jul 2, this machine): JsonBuf buffers returned via el_wrap_str
   were raw malloc, never arena-tracked — every engram_*_json call leaked
   its output unconditionally. Added jb_finish() arena-tracking across all
   ~30 return sites. Plus el_arena_push/pop per-tick bracketing support
   for the soul's awareness loop (the loop ran outside any request arena,
   so even correctly-tracked allocations were permanent — 7.5GB RSS in
   under a minute at 1s tick).

2. Corruption (Tim's container soak, docs findings/container-migration):
   stored engram node/edge fields (content, node_type, label, tier, tags,
   metadata, from/to ids) were arena el_strdup — freed at request end,
   leaving dangling pointers that read back as recycled request-buffer
   bytes one request later. This is the June corruption root cause and
   the mechanism that grew snapshot.json to 18GB of empty-type junk
   (21.6M nodes, 3,335 real). 39 sites switched to el_strdup_persist,
   plus a latent double-free fix in engram_load metadata fixup.

Interaction note: fix 1's per-tick arena reclamation makes fix 2
mandatory — more aggressive arena recycling widens the use-after-free
window if stored fields still live in the arena. Apply as a pair, never
separately.

Verified live: soul + engram rebuilt from this runtime, booted against
the recovered real snapshot (3,335 nodes/40,146 edges), 5h stable at
<100MB RSS, write-then-next-request field-integrity test passes (the
June corruption fingerprint does not reproduce). engram/dist/engram
binary updated from this build.

Investigation credit: leak diagnosis this machine Jul 2-6; corruption
diagnosis + persist-fix patch by Tim's instance (docs PR #4).
will.anderson merged commit 2b2a1246e7 into main 2026-07-13 21:23:39 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: neuron-technologies/el#64