Refactor handover context cleanup and fix memory leak in N2 handover source gNB path
- Add missing handover context cleanup in rrc_CU_process_ue_context_release_complete
- Fix 16-byte handover context leak in N2 handover source gNB trigger path
AddressSanitizer backtrace:
Direct leak of 16 byte(s) in 1 object(s) allocated from:
/#0 0x7fee67cb4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
/#1 0x58059e33454b in calloc_or_fail /home/guido/repo/openairinterface5g/develop/common/utils/utils.h:74
/#2 0x58059e33454b in alloc_ho_ctx /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:47
/#3 0x58059e339e4d in nr_rrc_trigger_n2_ho /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:556
/#4 0x58059e33ae93 in nr_HO_N2_trigger_telnet /home/guido/repo/openairinterface5g/develop/openair2/RRC/NR/rrc_gNB_mobility.c:611
Root cause: Handover context allocated in N2 handover source gNB trigger path (nr_rrc_trigger_n2_ho)
for any successful N2 handover but not properly freed in all handover completion scenarios.
The UE context release complete handler was missing cleanup for handover context.
Solution: refactor handover context cleanup
- Move nr_rrc_finalize_ho() call to rrc_delete_ue_data() for centralized cleanup
- Remove redundant nr_rrc_finalize_ho() calls from handover failure paths:
* rrc_CU_process_ue_context_release_request() - UE not deleted yet
* invalidate_du_connections() - UE will be deleted later
- Keep nr_rrc_finalize_ho() calls in handover success paths where UE continues operating
- Ensures handover context is cleaned up exactly once when UE is actually deleted
- Prevents potential double-free and use-after-free issues in handover cleanup
This centralizes all UE data cleanup in rrc_delete_ue_data() and ensures
handover context is properly managed throughout the UE lifecycle and cleaned up
when UE delete happens.
This commit is contained in:
@@ -2338,6 +2338,9 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p, sctp_as
|
||||
|
||||
static void rrc_delete_ue_data(gNB_RRC_UE_t *UE)
|
||||
{
|
||||
/* Clean up handover context if it exists */
|
||||
if (UE->ho_context)
|
||||
nr_rrc_finalize_ho(UE);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->UE_Capability_nr);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->masterCellGroup);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_MeasResults, UE->measResults);
|
||||
|
||||
@@ -453,10 +453,8 @@ static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id)
|
||||
RB_FOREACH(ue_context_p, rrc_nr_ue_tree_s, &rrc->rrc_ue_head) {
|
||||
gNB_RRC_UE_t *UE = &ue_context_p->ue_context;
|
||||
uint32_t ue_id = UE->rrc_ue_id;
|
||||
if (UE->ho_context != NULL) {
|
||||
if (UE->ho_context != NULL)
|
||||
LOG_W(NR_RRC, "DU disconnected while handover for UE %d active\n", ue_id);
|
||||
nr_rrc_finalize_ho(UE);
|
||||
}
|
||||
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_id);
|
||||
if (ue_data.du_assoc_id != assoc_id)
|
||||
continue; /* this UE is on another DU */
|
||||
|
||||
Reference in New Issue
Block a user