Fix SkHermesMessage payload-aliasing defect (task 3.8 findings log)
sk_hermes_send_one() -- the single funnel every sender, including sk_hermes_publish(), already goes through -- used to store the caller's own payload_addr pointer as-is. Two sends before either drains meant both messages pointed at the same caller-owned buffer, whichever send wrote last silently winning: real, confirmed live (a second identity thumbdrive attached at boot alongside Zuse's own left its WIREBIND pairing silently never happening). SkHermesMessage gains an inline payload_buf[SK_HERMES_CHUNK_MAX_ PAYLOAD] field; sk_hermes_send_one() now memcpy()s the caller's payload into it and points payload_addr at that copy instead. No sender or reader call site needed to change -- every existing reader already only ever reads through payload_addr, which still points at valid bytes of the same length, now message-owned. g_kh_blk_attach_buf/ g_kh_console_cmd_buf (repl.c, tasks 3.8/3.9) no longer need to survive past their own send call; their doc comments, which had claimed the old aliasing shape was benign, are corrected. Verified the original bug is actually gone: reproduced the exact original scenario (a real, sequentially-minted rajames identity attached at boot alongside Zuse's own, two simultaneous BLK-ATTACH- EVENT sends in one idle-loop pass) -- WIREBIND pairing, USE, and the Stage D relay all now work where WIREBIND previously silently failed. Standard three-ISA acceptance also clean: zero UNKNOWN WORD, dict_hash identical across all three and matching every prior acceptance run in this document. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
21734b1a52
commit
5c07745c18
@@ -496,10 +496,26 @@ int sk_hermes_send_one(VMUuid from, VMUuid to, uint32_t type, uint32_t channel_i
|
||||
|
||||
if (sk_hermes_alloc(from, &msg) != 0) return -1;
|
||||
|
||||
/* Real defect, found 2026-09-22 (FABRIC-3.6.md task 3.8's own
|
||||
* findings log): this used to store the caller's own payload_addr
|
||||
* as-is, a pointer this function does not own. Two sends before
|
||||
* either drains meant both messages pointed at the same
|
||||
* caller-owned buffer -- whichever send wrote last silently won.
|
||||
* Copy into this message's own payload_buf instead (kernel_hermes.h,
|
||||
* sized to SK_HERMES_CHUNK_MAX_PAYLOAD, the bound already enforced
|
||||
* above) and point payload_addr at that -- every message now owns
|
||||
* its payload bytes, independent of whatever the caller does with
|
||||
* its own buffer afterward. payload_len == 0 is a real, valid case
|
||||
* (an empty payload) -- memcpy of 0 bytes is well-defined even with
|
||||
* a NULL payload_addr -- guarded anyway (C's memcpy() is technically
|
||||
* undefined for a NULL argument even at length 0), matching this
|
||||
* project's own STRICT_PTR discipline elsewhere. */
|
||||
if (payload_len > 0) memcpy(msg->payload_buf, payload_addr, payload_len);
|
||||
msg->payload_addr = msg->payload_buf;
|
||||
|
||||
msg->type = type;
|
||||
msg->from = from;
|
||||
msg->to = to;
|
||||
msg->payload_addr = payload_addr;
|
||||
msg->payload_len = payload_len;
|
||||
msg->channel = channel_id;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user