Repository navigation
fix(init): deep-copy security_options in rmw_init_options_copy [P1] - #6
Conversation
67ce0d9 to
2245923
Compare
|
Reviewed the diff (+9/-0, single file The core fix is correct, minimal, and well-scoped: Two non-blocking follow-ups:
Neither blocks merge -- the shipped code is a correct, focused fix. Recommend both as fast-follow. |
Addresses the review findings on the durable-shm TRANSIENT_LOCAL change: - Return code (finding #1): the TL publish path ignored send_to's result and always returned RMW_RET_OK, even when the live send of the current message was rejected by the kernel size cap (EMSGSIZE) — a lying success, and inconsistent with the non-TL path. Extract the TL cache+replay+send logic into transient_local_publish(), which now surfaces ConfigError as RMW_RET_ERROR. (ENOBUFS/oversize on a raised-buffer machine stays a soft drop in BOTH paths, unchanged — a shared, pre-existing limitation.) - Serialized TL gap (completeness): rmw_publish_serialized_message did not feed the replay cache at all, so a large latched payload published through it was sent inline once and dropped for late joiners. It now routes TL through the same transient_local_publish() helper (durable staging + replay) and gained the same known-subscriber prune-on-refresh as rmw_publish. - Fallback coverage (finding #6): add a cold-path test seam (env var RMW_UDS_TEST_FORCE_SHM_FAILURE, checked only on large latched staging) so a test can force the shm-unavailable path and assert the payload is cached inline (no durable segment, no flag) and still delivered. Tests: TransientLocalPublishReturnsErrorOnEMSGSIZE and TransientLocalSerializedLargeMessageLateJoiner both confirmed to FAIL on the pre-change publisher and pass here; TransientLocalLargeMessageInlineFallbackWhenShmUnavailable covers the fallback. Full suite: 95 tests, clean build.
Severity: P1 — found by a full multi-agent code audit (method + findings in
AUDIT_FINAL.md).Problem
rmw_init_options_copy()did*dst = *srcand only deep-copiedenclave.rmw_security_options_t::security_root_pathis a heap-ownedchar *, so after the shallow copysrcanddstalias the same pointer.rmw_init_options_fini()callsrmw_security_options_fini(), so finalizing both copies (what rcl / init-options lifecycle code does) freessecurity_root_pathtwice → heap corruption. Latent until a security-enabled (sros2) deployment sets a non-null root.Fix
After
*dst = *src, zerodst->security_optionsand deep-copy viarmw_security_options_copy(...), returning the error on failure.File:
rmw_unix_socket_cpp/src/rmw_init.cppNote: the analogous
discovery_optionsaliasing (P2-4) is addressed in the full-stack PR, not here.Build: clean.