From 691d8ea13a6d84b99829475c849aa7378b3ebd43 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sun, 21 May 2023 07:51:43 +0900 Subject: [PATCH] [AMF] Fixed crashes with assertion (#2312) AMF crashes with amf_nnssf_nsselection_handle_get assertion failure. --- src/amf/nnssf-handler.c | 7 ++++ src/amf/npcf-build.c | 8 +--- src/amf/nsmf-build.c | 8 +--- src/amf/nsmf-handler.c | 82 ++++++++++++++++++++++++--------------- src/amf/nudm-handler.c | 16 ++++---- tests/common/ngap-build.c | 44 ++++++++++++++++++++- tests/common/ngap-build.h | 4 +- 7 files changed, 113 insertions(+), 56 deletions(-) diff --git a/src/amf/nnssf-handler.c b/src/amf/nnssf-handler.c index 92c0b4e42..962d8a52f 100644 --- a/src/amf/nnssf-handler.c +++ b/src/amf/nnssf-handler.c @@ -34,6 +34,7 @@ int amf_nnssf_nsselection_handle_get( OpenAPI_nsi_information_t *NsiInformation = NULL; amf_ue_t *amf_ue = NULL; + ran_ue_t *ran_ue = NULL; ogs_assert(sess); amf_ue = sess->amf_ue; @@ -42,6 +43,12 @@ int amf_nnssf_nsselection_handle_get( ogs_assert(!SESSION_CONTEXT_IN_SMF(sess)); + ran_ue = ran_ue_cycle(amf_ue->ran_ue); + if (!ran_ue) { + ogs_error("NG context has already been removed"); + return OGS_ERROR; + } + if (recvmsg->res_status != OGS_SBI_HTTP_STATUS_OK) { ogs_error("[%s] HTTP response error [%d]", amf_ue->supi, recvmsg->res_status); diff --git a/src/amf/npcf-build.c b/src/amf/npcf-build.c index 9a8a6da8c..cf0b59e1d 100644 --- a/src/amf/npcf-build.c +++ b/src/amf/npcf-build.c @@ -38,6 +38,7 @@ ogs_sbi_request_t *amf_npcf_am_policy_control_build_create( ogs_assert(amf_ue); ogs_assert(amf_ue->supi); + ogs_assert(ran_ue_cycle(amf_ue->ran_ue)); memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST; @@ -50,13 +51,6 @@ ogs_sbi_request_t *amf_npcf_am_policy_control_build_create( memset(&ueLocation, 0, sizeof(ueLocation)); memset(&UeAmbr, 0, sizeof(UeAmbr)); - ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue); - if (!ran_ue) { - ogs_error("NG context has already been removed"); - /* ran_ue is required for amf_ue_rat_type() */ - goto end; - } - server = ogs_list_first(&ogs_sbi_self()->server_list); if (!server) { ogs_error("No server"); diff --git a/src/amf/nsmf-build.c b/src/amf/nsmf-build.c index 1d1464d55..c776edea9 100644 --- a/src/amf/nsmf-build.c +++ b/src/amf/nsmf-build.c @@ -42,6 +42,7 @@ ogs_sbi_request_t *amf_nsmf_pdusession_build_create_sm_context( amf_ue = sess->amf_ue; ogs_assert(amf_ue); ogs_assert(amf_ue->nas.access_type); + ogs_assert(ran_ue_cycle(amf_ue->ran_ue)); memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST; @@ -56,13 +57,6 @@ ogs_sbi_request_t *amf_nsmf_pdusession_build_create_sm_context( memset(&header, 0, sizeof(header)); memset(&ueLocation, 0, sizeof(ueLocation)); - ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue); - if (!ran_ue) { - /* ran_ue is required for amf_ue_rat_type() */ - ogs_error("NG context has already been removed"); - goto end; - } - SmContextCreateData.serving_nf_id = NF_INSTANCE_ID(ogs_sbi_self()->nf_instance); if (!SmContextCreateData.serving_nf_id) { diff --git a/src/amf/nsmf-handler.c b/src/amf/nsmf-handler.c index 4a0d436a0..6ae46b1cb 100644 --- a/src/amf/nsmf-handler.c +++ b/src/amf/nsmf-handler.c @@ -239,23 +239,29 @@ int amf_nsmf_pdusession_handle_update_sm_context( AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) && AMF_SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST)) { + ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue); - if (!PCF_AM_POLICY_ASSOCIATED(amf_ue)) { - r = amf_ue_sbi_discover_and_send( - OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, - NULL, - amf_npcf_am_policy_control_build_create, - amf_ue, 0, NULL); - ogs_expect(r == OGS_OK); - ogs_assert(r != OGS_ERROR); + if (ran_ue) { + if (!PCF_AM_POLICY_ASSOCIATED(amf_ue)) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, + NULL, + amf_npcf_am_policy_control_build_create, + amf_ue, 0, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } else { + CLEAR_AMF_UE_TIMER(amf_ue->t3550); + r = nas_5gs_send_registration_accept(amf_ue); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + + AMF_UE_CLEAR_N2_TRANSFER(amf_ue, + pdu_session_resource_setup_request); + } } else { - CLEAR_AMF_UE_TIMER(amf_ue->t3550); - r = nas_5gs_send_registration_accept(amf_ue); - ogs_expect(r == OGS_OK); - ogs_assert(r != OGS_ERROR); - - AMF_UE_CLEAR_N2_TRANSFER( - amf_ue, pdu_session_resource_setup_request); + ogs_warn("[%s] RAN-NG Context has already " + "been removed", amf_ue->supi); } } } else if (state == AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST) { @@ -584,6 +590,7 @@ int amf_nsmf_pdusession_handle_update_sm_context( } else if (state == AMF_UPDATE_SM_CONTEXT_DUPLICATED_PDU_SESSION_ID) { + ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue); /* * 1. PDU session establishment request * (Duplicated PDU Session ID) @@ -594,12 +601,17 @@ int amf_nsmf_pdusession_handle_update_sm_context( ogs_warn("[%s:%d] Receive Update SM context" "(DUPLICATED_PDU_SESSION_ID)", amf_ue->supi, sess->psi); - r = amf_sess_sbi_discover_and_send( - OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL, - amf_nsmf_pdusession_build_create_sm_context, - sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL); - ogs_expect(r == OGS_OK); - ogs_assert(r != OGS_ERROR); + if (ran_ue) { + r = amf_sess_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL, + amf_nsmf_pdusession_build_create_sm_context, + sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } else { + ogs_warn("[%s] RAN-NG Context has already been removed", + amf_ue->supi); + } } else if (state == AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST) { @@ -890,19 +902,25 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state) amf_ue, AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) && AMF_SESSION_SYNC_DONE( amf_ue, AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST)) { + ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue); - if (!PCF_AM_POLICY_ASSOCIATED(amf_ue)) { - r = amf_ue_sbi_discover_and_send( - OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL, - amf_npcf_am_policy_control_build_create, - amf_ue, 0, NULL); - ogs_expect(r == OGS_OK); - ogs_assert(r != OGS_ERROR); + if (ran_ue) { + if (!PCF_AM_POLICY_ASSOCIATED(amf_ue)) { + r = amf_ue_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL, NULL, + amf_npcf_am_policy_control_build_create, + amf_ue, 0, NULL); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } else { + CLEAR_AMF_UE_TIMER(amf_ue->t3550); + r = nas_5gs_send_registration_accept(amf_ue); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + } } else { - CLEAR_AMF_UE_TIMER(amf_ue->t3550); - r = nas_5gs_send_registration_accept(amf_ue); - ogs_expect(r == OGS_OK); - ogs_assert(r != OGS_ERROR); + ogs_warn("[%s] RAN-NG Context has already been removed", + amf_ue->supi); } } diff --git a/src/amf/nudm-handler.c b/src/amf/nudm-handler.c index c6a471514..cf61f82b9 100644 --- a/src/amf/nudm-handler.c +++ b/src/amf/nudm-handler.c @@ -26,20 +26,21 @@ int amf_nudm_sdm_handle_provisioned( amf_ue_t *amf_ue, int state, ogs_sbi_message_t *recvmsg) { int i, r; + ran_ue_t *ran_ue = NULL; ogs_assert(amf_ue); ogs_assert(recvmsg); + ran_ue = ran_ue_cycle(amf_ue->ran_ue); + if (!ran_ue) { + /* ran_ue is required for amf_ue_is_rat_restricted() */ + ogs_error("NG context has already been removed"); + return OGS_ERROR; + } + SWITCH(recvmsg->h.resource.component[1]) CASE(OGS_SBI_RESOURCE_NAME_AM_DATA) - ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue); - if (!ran_ue) { - /* ran_ue is required for amf_ue_is_rat_restricted() */ - ogs_error("NG context has already been removed"); - return OGS_ERROR; - } - if (recvmsg->AccessAndMobilitySubscriptionData) { OpenAPI_list_t *gpsiList = recvmsg->AccessAndMobilitySubscriptionData->gpsis; @@ -242,7 +243,6 @@ int amf_nudm_sdm_handle_provisioned( break; CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA) - if (amf_ue->data_change_subscription_id) { /* we already have a SDM subscription to UDM; continue without * subscribing again */ diff --git a/tests/common/ngap-build.c b/tests/common/ngap-build.c index 761541e11..1f2a65436 100644 --- a/tests/common/ngap-build.c +++ b/tests/common/ngap-build.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019,2020 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -2595,3 +2595,45 @@ static ogs_pkbuf_t *testngap_build_handover_request_ack_transfer( return ogs_asn_encode( &asn_DEF_NGAP_HandoverRequestAcknowledgeTransfer, &message); } + +#define TEST_NGAP_MAX_MESSAGE 64 + +ogs_pkbuf_t *test_ngap_build_amf_configuration_ack(int i) +{ + ogs_pkbuf_t *pkbuf = NULL; + const char *payload[TEST_NGAP_MAX_MESSAGE] = { + "2000 000f000002000a40 0200010055400200 01", + "", + "", + + "", + "", + "", + + "", + "", + "", + + }; + uint16_t len[TEST_NGAP_MAX_MESSAGE] = { + 19, + 0, + 0, + + 0, + 0, + 0, + + 0, + 0, + 0, + }; + char hexbuf[OGS_HUGE_LEN]; + + pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN); + ogs_assert(pkbuf); + ogs_pkbuf_put_data(pkbuf, + ogs_hex_from_string(payload[i], hexbuf, sizeof(hexbuf)), len[i]); + + return pkbuf; +} diff --git a/tests/common/ngap-build.h b/tests/common/ngap-build.h index eedbfc9da..47e3615ba 100644 --- a/tests/common/ngap-build.h +++ b/tests/common/ngap-build.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019,2020 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -79,6 +79,8 @@ ogs_pkbuf_t *testngap_build_handover_failure(test_ue_t *test_ue, ogs_pkbuf_t *testngap_build_handover_cancel(test_ue_t *test_ue, NGAP_Cause_PR group, long cause); +ogs_pkbuf_t *test_ngap_build_amf_configuration_ack(int i); + #ifdef __cplusplus } #endif