Files
openairinterface5g/openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h
T
makiandClaude Opus 4.7 08349f246b RC SM: fix heap corruption on UE teardown after rrcRelease event
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>
2026-05-16 18:55:45 +09:00

29 lines
1.2 KiB
C

/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#ifndef RAN_FUNC_SM_RAN_CTRL_EXTERN_AGENT_H
#define RAN_FUNC_SM_RAN_CTRL_EXTERN_AGENT_H
#include "openair2/RRC/NR/nr_rrc_defs.h"
#include "openair2/E2AP/flexric/src/lib/3gpp/ie/rrc_msg_id.h"
#include "openair2/E2AP/flexric/src/lib/3gpp/ie/network_interface_type.h"
#include "openair2/E2AP/flexric/src/sm/rc_sm/ie/ir/rrc_state.h"
void signal_rrc_msg(const nr_rrc_class_e nr_channel, const uint32_t rrc_msg_id, const byte_array_t rrc_ba);
void signal_ue_id(const gNB_RRC_UE_t *rrc_ue_context, const uint16_t class, const uint32_t msg_id);
void signal_rrc_state_changed_to(const gNB_RRC_UE_t *rrc_ue_context, const rrc_state_e2sm_rc_e rrc_state);
/* Serialize UE-context teardown against in-flight RC indications.
* Without this, signal_rrc_msg(rrcRelease) can hand a malloc'd indication
* to the async E2 agent thread; if the gNB then frees the UE state while
* the agent is still encoding, glibc detects heap corruption ("double free
* or corruption (!prev)") and the process aborts.
* The teardown caller must wrap rrc_gNB_remove_ue_context() in these. */
void rc_teardown_lock(void);
void rc_teardown_unlock(void);
#endif