Summary
Zephyr 4.4 added CONFIG_SYS_HEAP_HARDENING to lib/heap/heap.c — per-chunk canaries, poisoning on free, and three hardening tiers (BASIC/MODERATE/FULL). Our zephyr/gale_heap.c was forked from a pre-4.4 upstream and has none of it. When users enable CONFIG_GALE_KERNEL_HEAP=y, they silently lose the runtime hardening in exchange for Verus proofs.
Concrete diff
Upstream (lib/heap/heap.c):
HEAP_CANARY_MAGIC 0x5A6B7C8D9EAFB0C1ULL / HEAP_CANARY_POISON 0xDEADBEEFDEADBEEFULL
compute_canary() / set_chunk_canary() / verify_chunk_canary()
SYS_HEAP_HARDENING_BASIC / _MODERATE / _FULL gates throughout
Ours (gale/zephyr/gale_heap.c): none of the above.
Why this matters
Gale's pitch is "strictly safer than upstream heap." Today that's false for users who want both formal verification AND runtime hardening — they cannot have both. That's a silent regression, not a documented tradeoff, which is worse.
Options
-
Port the hardening code into gale_heap.c. Preserves the replacement model; keeps gale's verification path. Cost: carrying more diff from upstream forever, re-porting on each Zephyr release.
-
Stop replacing heap.c. Let upstream's (hardened) heap handle allocation; expose Gale's verified model as a separate check layer callable at boundaries. Cost: architectural change to how gale composes with Zephyr; possibly removes some of gale's performance claims.
-
Document the tradeoff honestly and let users choose. Ship both, users pick runtime canaries vs formal proof (or combine them if feasible). Cost: doesn't fix the underlying gap, just makes it visible.
Recommendation
Option 2 in the long run — gale's value is the formal model, not carrying a heap fork. In the short term, Option 3 is minimum viable (a clear note in the README and in gale_overlay.conf comments).
Related
Summary
Zephyr 4.4 added
CONFIG_SYS_HEAP_HARDENINGtolib/heap/heap.c— per-chunk canaries, poisoning on free, and three hardening tiers (BASIC/MODERATE/FULL). Ourzephyr/gale_heap.cwas forked from a pre-4.4 upstream and has none of it. When users enableCONFIG_GALE_KERNEL_HEAP=y, they silently lose the runtime hardening in exchange for Verus proofs.Concrete diff
Upstream (
lib/heap/heap.c):HEAP_CANARY_MAGIC 0x5A6B7C8D9EAFB0C1ULL/HEAP_CANARY_POISON 0xDEADBEEFDEADBEEFULLcompute_canary()/set_chunk_canary()/verify_chunk_canary()SYS_HEAP_HARDENING_BASIC/_MODERATE/_FULLgates throughoutOurs (
gale/zephyr/gale_heap.c): none of the above.Why this matters
Gale's pitch is "strictly safer than upstream heap." Today that's false for users who want both formal verification AND runtime hardening — they cannot have both. That's a silent regression, not a documented tradeoff, which is worse.
Options
Port the hardening code into
gale_heap.c. Preserves the replacement model; keeps gale's verification path. Cost: carrying more diff from upstream forever, re-porting on each Zephyr release.Stop replacing heap.c. Let upstream's (hardened) heap handle allocation; expose Gale's verified model as a separate check layer callable at boundaries. Cost: architectural change to how gale composes with Zephyr; possibly removes some of gale's performance claims.
Document the tradeoff honestly and let users choose. Ship both, users pick runtime canaries vs formal proof (or combine them if feasible). Cost: doesn't fix the underlying gap, just makes it visible.
Recommendation
Option 2 in the long run — gale's value is the formal model, not carrying a heap fork. In the short term, Option 3 is minimum viable (a clear note in the README and in
gale_overlay.confcomments).Related