[AMF/MME] Fix segfault on NG/S1 handover cancel by checking for NULL target UE (#3789)

When a UE handover occurs, the target UE may already be removed. This
patch adds a NULL pointer check and logs an error instead of causing a
segmentation fault in both enb and sgw deassociation functions.
This commit is contained in:
Sukchan Lee
2025-03-21 20:27:49 +09:00
parent fa3edde329
commit a5510f1870
2 changed files with 65 additions and 18 deletions

View File

@@ -2263,20 +2263,37 @@ void source_ue_deassociate_target_ue(ran_ue_t *ran_ue)
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
if (target_ue) {
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
} else
ogs_error("Target-UE-ID [%d] has already been removed "
"(RAN_UE_S1AP_ID[%lld] AMF_UE_S1AP_ID[%lld])",
source_ue->target_ue_id,
(long long)source_ue->ran_ue_ngap_id,
(long long)source_ue->amf_ue_ngap_id);
} else if (ran_ue->source_ue_id >= OGS_MIN_POOL_ID &&
ran_ue->source_ue_id <= OGS_MAX_POOL_ID) {
target_ue = ran_ue;
source_ue = ran_ue_find_by_id(ran_ue->source_ue_id);
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
if (source_ue) {
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
} else
ogs_error("Source-UE-ID [%d] has already been removed "
"(RAN_UE_S1AP_ID[%lld] AMF_UE_S1AP_ID[%lld])",
target_ue->source_ue_id,
(long long)target_ue->ran_ue_ngap_id,
(long long)target_ue->amf_ue_ngap_id);
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
}
}

View File

@@ -4200,20 +4200,36 @@ void enb_ue_source_deassociate_target(enb_ue_t *enb_ue)
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
if (target_ue) {
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
} else
ogs_error("Target-UE-ID [%d] has already been removed "
"(ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d])",
source_ue->target_ue_id,
source_ue->enb_ue_s1ap_id, source_ue->mme_ue_s1ap_id);
} else if (enb_ue->source_ue_id >= OGS_MIN_POOL_ID &&
enb_ue->source_ue_id <= OGS_MAX_POOL_ID) {
target_ue = enb_ue;
source_ue = enb_ue_find_by_id(enb_ue->source_ue_id);
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
if (source_ue) {
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
} else
ogs_error("Source-UE-ID [%d] has already been removed "
"(ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d])",
target_ue->source_ue_id,
target_ue->enb_ue_s1ap_id, target_ue->mme_ue_s1ap_id);
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
}
}
@@ -4253,6 +4269,7 @@ void sgw_ue_source_deassociate_target(sgw_ue_t *sgw_ue)
{
sgw_ue_t *source_ue = NULL;
sgw_ue_t *target_ue = NULL;
ogs_assert(sgw_ue);
if (sgw_ue->target_ue_id >= OGS_MIN_POOL_ID &&
@@ -4262,20 +4279,33 @@ void sgw_ue_source_deassociate_target(sgw_ue_t *sgw_ue)
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
if (target_ue) {
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
} else
ogs_error("Target-UE-ID [%d] has already been removed "
"(SGW-S11-TEID[%d])",
source_ue->target_ue_id, source_ue->sgw_s11_teid);
} else if (sgw_ue->source_ue_id >= OGS_MIN_POOL_ID &&
sgw_ue->source_ue_id <= OGS_MAX_POOL_ID) {
target_ue = sgw_ue;
source_ue = sgw_ue_find_by_id(sgw_ue->source_ue_id);
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
if (source_ue) {
ogs_assert(source_ue->target_ue_id >= OGS_MIN_POOL_ID &&
source_ue->target_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
} else
ogs_error("Source-UE-ID [%d] has already been removed "
"(SGW-S11-TEID[%d])",
target_ue->source_ue_id, target_ue->sgw_s11_teid);
ogs_assert(target_ue->source_ue_id >= OGS_MIN_POOL_ID &&
target_ue->source_ue_id <= OGS_MAX_POOL_ID);
source_ue->target_ue_id = OGS_INVALID_POOL_ID;
target_ue->source_ue_id = OGS_INVALID_POOL_ID;
}
}