[AMF] fix the crash (#1280)

During PDU Session Establishment,
if gNB sends PDUSessionResourceReleaseResponse,
AMF was crashed.

In this case, AMF/SMF remove Session Context and sends ErrorIndication.
This commit is contained in:
Sukchan Lee 2021-12-11 20:35:16 +09:00
parent 74bbc6ecbf
commit 07a61018b2
6 changed files with 1101 additions and 3 deletions

View File

@ -722,6 +722,25 @@ void source_ue_associate_target_ue(ran_ue_t *source_ue, ran_ue_t *target_ue);
void source_ue_deassociate_target_ue(ran_ue_t *ran_ue);
amf_sess_t *amf_sess_add(amf_ue_t *amf_ue, uint8_t psi);
/*
* If there is SBI transaction,
* we will not remove session context at this point.
*/
#define AMF_SESS_CLEAR(__sESS) \
do { \
ogs_sbi_object_t *sbi_object = NULL; \
ogs_assert(__sESS); \
sbi_object = &sess->sbi; \
ogs_assert(sbi_object); \
\
if (ogs_list_count(&sbi_object->xact_list)) { \
ogs_error("SBI running [%d]", \
ogs_list_count(&sbi_object->xact_list)); \
} else { \
amf_sess_remove(__sESS); \
} \
} while(0)
void amf_sess_remove(amf_sess_t *sess);
void amf_sess_remove_all(amf_ue_t *amf_ue);
amf_sess_t *amf_sess_find_by_psi(amf_ue_t *amf_ue, uint8_t psi);

View File

@ -42,6 +42,8 @@ int amf_nsmf_pdusession_handle_create_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -56,6 +58,8 @@ int amf_nsmf_pdusession_handle_create_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -68,6 +72,8 @@ int amf_nsmf_pdusession_handle_create_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -97,6 +103,8 @@ int amf_nsmf_pdusession_handle_create_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
}
@ -120,6 +128,8 @@ int amf_nsmf_pdusession_handle_create_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
if (!SmContextCreateError->error) {
@ -128,6 +138,8 @@ int amf_nsmf_pdusession_handle_create_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -145,6 +157,8 @@ int amf_nsmf_pdusession_handle_create_sm_context(
ogs_assert(OGS_OK ==
nas_5gs_send_gsm_reject(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
}
@ -153,6 +167,8 @@ int amf_nsmf_pdusession_handle_create_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -203,6 +219,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
amf_ue->supi, sess->psi);
nas_5gs_send_gmm_reject(amf_ue,
OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -270,6 +288,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -280,6 +300,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -307,6 +329,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -317,6 +341,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
nas_5gs_send_back_gsm_message(sess,
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
AMF_NAS_BACKOFF_TIME));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -343,6 +369,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -366,6 +394,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -692,6 +722,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ogs_assert(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
if (!SmContextUpdateError->error) {
@ -700,6 +732,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ogs_assert(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -717,6 +751,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ogs_assert(OGS_OK ==
nas_5gs_send_gsm_reject(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
}
@ -728,6 +764,8 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ogs_assert(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
@ -739,16 +777,17 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ogs_assert(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}
#endif
ogs_error("[%d:%d] HTTP response error [%d]",
sess->psi, sess->pti, recvmsg->res_status);
ogs_assert(OGS_OK ==
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error));
AMF_SESS_CLEAR(sess);
return OGS_ERROR;
}

View File

@ -396,9 +396,26 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
case OpenAPI_n2_sm_info_type_PDU_RES_REL_RSP:
ngap_state = sess->ngap_state.pdu_session_resource_release;
if (ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED ||
if (ngap_state == SMF_NGAP_STATE_NONE) {
strerror = ogs_msprintf(
"[%s:%d] No PDUSessionResourceReleaseRequest",
smf_ue->supi, sess->psi);
ogs_assert(strerror);
ogs_error("%s", strerror);
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL));
ogs_free(strerror);
OGS_FSM_TRAN(s, smf_gsm_state_exception);
} else if (
ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED ||
ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED) {
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
} else if (ngap_state ==
SMF_NGAP_STATE_ERROR_INDICATION_RECEIVED_FROM_5G_AN) {
smf_n1_n2_message_transfer_param_t param;

View File

@ -28,6 +28,7 @@ abts_suite *test_identity(abts_suite *suite);
abts_suite *test_gmm_status(abts_suite *suite);
abts_suite *test_ue_context(abts_suite *suite);
abts_suite *test_reset(abts_suite *suite);
abts_suite *test_crash(abts_suite *suite);
const struct testlist {
abts_suite *(*func)(abts_suite *suite);
@ -41,6 +42,9 @@ const struct testlist {
{test_gmm_status},
{test_ue_context},
{test_reset},
#if 0 /* Since there is error LOG, we disabled the following test */
{test_crash},
#endif
{NULL},
};

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@ test5gc_registration_sources = files('''
gmm-status-test.c
ue-context-test.c
reset-test.c
crash-test.c
'''.split())
test5gc_registration_exe = executable('registration',