When xApp subscribes to RC SM Style 1 (Message Copy), the gNB's
signal_rrc_msg() path on rrcRelease handed an async indication to the
E2 agent thread, then the calling code proceeded to UE-context
teardown while the encoder was still walking the indication structure.
Three issues observed in production:
1. malloc_or_fail() leaves union/pointer fields in rc_ind_data and its
sub-structures uninitialized; the encoder dereferences whatever
garbage was in the unused union member and corrupts the heap.
Fix: switch malloc_or_fail(sizeof(...)) to
calloc_or_fail(1, sizeof(...)) in fill_rrc_msg_copy, fill_ue_id,
and the rc_ind_data_t allocations.
2. The async indication path runs concurrently with UE-context
removal. Add rc_teardown_lock/rc_teardown_unlock helpers (public
wrappers around rc_mutex) so the RRC layer can serialize teardown
against any in-flight signal_rrc_msg() critical section.
3. Wrap rrc_gNB_remove_ue_context() in rrc_gNB.c with
rc_teardown_lock/unlock under E2_AGENT.
With these three fixes plus the deployment-side MALLOC_CHECK_=3
backstop, a 20-minute challenging-schedule run completes with 22
RRC_RELEASE events processed cleanly and zero crashes (vs. SIGSEGV
within 10-30 minutes previously).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>