mirror of
https://github.com/open5gs/open5gs.git
synced 2025-10-22 23:31:57 +00:00
[AMF] Fix crash on malformed NGSetupRequest PLMNIdentity
When the NGSetupRequest contains an invalid GlobalRANNodeID or BroadcastPLMNItem with a malformed PLMNIdentity, the AMF previously performed memcpy() without checking the buffer size. This could lead to invalid memory access and crash. Fix by validating PLMNIdentity size against sizeof(ogs_plmn_id_t) and sending NGSetupFailure with CauseProtocol_semantic_error if invalid. Also add regression tests: - Build malformed NGSetupRequest with incorrect PLMNIdentity size - Verify AMF does not crash and returns NGSetupFailure This resolves the crash reported in issue #4087.
This commit is contained in:
@@ -183,6 +183,18 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message)
|
||||
return;
|
||||
}
|
||||
|
||||
if (globalGNB_ID->pLMNIdentity.size != sizeof(gnb->plmn_id)) {
|
||||
ogs_error("Invalid PLMNIdentity size = %d (expected %d)",
|
||||
(int)globalGNB_ID->pLMNIdentity.size,
|
||||
(int)sizeof(gnb->plmn_id));
|
||||
group = NGAP_Cause_PR_protocol;
|
||||
cause = NGAP_CauseProtocol_semantic_error;
|
||||
r = ngap_send_ng_setup_failure(gnb, group, cause);
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SupportedTAList) {
|
||||
ogs_error("No SupportedTAList");
|
||||
group = NGAP_Cause_PR_protocol;
|
||||
@@ -274,6 +286,18 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message)
|
||||
&BroadcastPLMNItem->pLMNIdentity;
|
||||
ogs_assert(pLMNIdentity);
|
||||
|
||||
if (pLMNIdentity->size != sizeof(ogs_plmn_id_t)) {
|
||||
ogs_error("Invalid PLMNIdentity size = %d (expected %d)",
|
||||
(int)pLMNIdentity->size,
|
||||
(int)sizeof(ogs_plmn_id_t));
|
||||
group = NGAP_Cause_PR_protocol;
|
||||
cause = NGAP_CauseProtocol_semantic_error;
|
||||
r = ngap_send_ng_setup_failure(gnb, group, cause);
|
||||
ogs_expect(r == OGS_OK);
|
||||
ogs_assert(r != OGS_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&gnb->supported_ta_list[i].bplmn_list[j].plmn_id,
|
||||
pLMNIdentity->buf, sizeof(ogs_plmn_id_t));
|
||||
ogs_debug(" PLMN_ID[MCC:%d MNC:%d]",
|
||||
|
@@ -2622,6 +2622,31 @@ static ogs_pkbuf_t *testngap_build_handover_request_ack_transfer(
|
||||
|
||||
#define TEST_NGAP_MAX_MESSAGE 64
|
||||
|
||||
ogs_pkbuf_t *test_ngap_build_malformed_ng_setup_request(int i)
|
||||
{
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
const char *payload[TEST_NGAP_MAX_MESSAGE] = {
|
||||
"00150035"
|
||||
"000004001b0008c0 02f8391000010200 5240090300667265 6535676300660010"
|
||||
"00000000010002f8 3900001008010203 0015400140000000",
|
||||
"",
|
||||
};
|
||||
|
||||
uint16_t len[TEST_NGAP_MAX_MESSAGE] = {
|
||||
60,
|
||||
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;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *test_ngap_build_amf_configuration_ack(int i)
|
||||
{
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
@@ -79,6 +79,7 @@ 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_malformed_ng_setup_request(int i);
|
||||
ogs_pkbuf_t *test_ngap_build_amf_configuration_ack(int i);
|
||||
ogs_pkbuf_t *test_ngap_build_malformed_initial_ue_message(int i);
|
||||
|
||||
|
@@ -1434,6 +1434,29 @@ static void test5_func(abts_case *tc, void *data)
|
||||
testgnb_ngap_close(ngap);
|
||||
}
|
||||
|
||||
static void test6_issues4087_func(abts_case *tc, void *data)
|
||||
{
|
||||
int rv;
|
||||
ogs_socknode_t *ngap;
|
||||
ogs_pkbuf_t *sendbuf;
|
||||
ogs_pkbuf_t *recvbuf;
|
||||
ogs_ngap_message_t message;
|
||||
|
||||
ngap = testngap_client(1, AF_INET);
|
||||
ABTS_PTR_NOTNULL(tc, ngap);
|
||||
|
||||
sendbuf = test_ngap_build_malformed_ng_setup_request(0);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
ogs_pkbuf_free(recvbuf);
|
||||
|
||||
testgnb_ngap_close(ngap);
|
||||
}
|
||||
|
||||
abts_suite *test_crash(abts_suite *suite)
|
||||
{
|
||||
suite = ADD_SUITE(suite)
|
||||
@@ -1443,6 +1466,7 @@ abts_suite *test_crash(abts_suite *suite)
|
||||
abts_run_test(suite, test3_func, NULL);
|
||||
abts_run_test(suite, test4_issues2842_func, NULL);
|
||||
abts_run_test(suite, test5_func, NULL);
|
||||
abts_run_test(suite, test6_issues4087_func, NULL);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
Reference in New Issue
Block a user