fix(controller): CtrlHelloRequest.key Data field crashed HA leader election (bug-1835)
CtrlHelloRequest.key was declared `Data` in controller.capnp. This project's capnp-c backend silently no-ops encoding of Data-typed fields without zero-initializing the caller's local struct, leaving an uninitialized capn_ptr that write_CtrlHelloRequest unconditionally wrote to the wire -- SIGSEGV in capn_setp/copy_ptr. Hit live: ctrl-1 won its Raft election and crashed calling ha_send_ctrlhello_to_all_standbys(). Same bug class as bug-1504/bug-1505, both already fixed by switching the field from Data to List(UInt8); bug-1505's own writeup had flagged CtrlHelloRequest.key as a known-but-unfixed instance. Applied the identical fix here: Data -> List(UInt8) + keyLen companion in the schema, uint8_t*/key_len in typemap.h. The field is unused in production (always NULL), so no consumer code changed. Added a round-trip regression test covering both the NULL-key production shape and real key content. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
1e43345b2e
commit
cd9ecb4159
7 changed files with 197 additions and 21 deletions
|
|
@ -1142,9 +1142,23 @@ struct WalCatchupEntry $C.mapname("wal_catchup_entry_t") {
|
|||
|
||||
struct CtrlHelloRequest $C.mapname("ctrl_hello_req_t") {
|
||||
name @0 :Text $C.mapname("name");
|
||||
key @1 :Data $C.mapname("key");
|
||||
# key is List(UInt8), NOT Data (fixes a live production SIGSEGV, same bug
|
||||
# class as bug-1504/bug-1505 -- see SnapshotData.internalState/
|
||||
# WalCatchupEntry.payload above for the full root cause: this codebase's
|
||||
# capnpc-c backend silently no-ops every Data-typed field's encoding in
|
||||
# the generated encode_XXX() helper without zero-initializing the
|
||||
# caller's local struct first, leaving a genuinely uninitialized capn_ptr
|
||||
# written onto the wire by write_XXX(). bug-1505's own writeup already
|
||||
# flagged "CtrlHelloRequest.key" as a known-but-unfixed instance of this
|
||||
# gap; it went on to actually crash a live 3-node HA cluster (SIGSEGV in
|
||||
# write_CtrlHelloRequest via encode_CtrlHelloRequest_ptr) the moment a
|
||||
# newly-elected primary called ha_send_ctrlhello_to_all_standbys() --
|
||||
# confirming the risk was real, not theoretical. keyLen (@4, below) is
|
||||
# its maplistcount companion.
|
||||
key @1 :List(UInt8) $C.mapname("key") $C.maplistcount("key_len");
|
||||
appliedLsn @2 :UInt64 $C.mapname("applied_lsn");
|
||||
configTag @3 :UInt64 $C.mapname("config_tag");
|
||||
keyLen @4 :UInt32 $C.mapname("key_len");
|
||||
}
|
||||
|
||||
struct CtrlHelloReply $C.mapname("ctrl_hello_reply_t") {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue