提交 #818586: Open5GS NRF/UDM/UDR/NSSF/BSF/PCF/AMF/AUSF/SMF v2.7.7 Denial of Service信息

标题Open5GS NRF/UDM/UDR/NSSF/BSF/PCF/AMF/AUSF/SMF v2.7.7 Denial of Service
描述### Open5GS Release, Revision, or Tag v2.7.7 ### Steps to reproduce ### Description Open5GS uses a shared nghttp2-based SBI server in `../lib/sbi/nghttp2-server.c` across its HTTP/2 SBI network functions. During request-header processing, the server allocates one `ogs_sbi_stream_t` from the global `stream_pool` and one `ogs_sbi_request_t` from the global `request_pool` before route dispatch: ```c ogs_pool_id_calloc(&stream_pool, &stream); if (!stream) { ogs_error("ogs_pool_id_calloc() failed"); return NULL; } stream->request = ogs_sbi_request_new(); if (!stream->request) { ogs_error("ogs_sbi_request_new() failed"); ogs_pool_id_free(&stream_pool, stream); return NULL; } ``` `on_begin_headers()` then unconditionally asserts that the allocation succeeded: ```c stream = stream_add(sbi_sess, frame->hd.stream_id); ogs_assert(stream); ``` The same pool sizing is initialized centrally for all SBI NFs: ```c #define POOL_NUM_PER_UE 16 ogs_app()->pool.message = global_conf.max.ue * POOL_NUM_PER_UE; ogs_app()->pool.stream = global_conf.max.ue * POOL_NUM_PER_UE; ``` Because allocation happens as soon as request headers arrive, the issue is not limited to business flows that wait on an upstream NF. A client can keep large numbers of HTTP/2 requests pending simply by opening streams with headers and never finishing the request body. In Docker validation, that generic "hold-open" pattern reproduced the same `on_begin_headers` assertion across every tested SBI NF in the basic deployment. ### Root cause - Shared crash site: `../lib/sbi/nghttp2-server.c:1629` - Immediate allocation failure site: `../lib/sbi/nghttp2-server.c:758` - Shared request-pool allocator: `../lib/sbi/message.c:253-256` - Shared pool initialization: `../lib/sbi/context.c:46-48` and `../lib/app/ogs-config.c:71-78` - Bug class: stream / request pool exhaustion leading to assertion abort - Controlling factor: number of concurrent HTTP/2 request streams left pending after request headers are accepted ### Tested impact The following SBI NFs were validated in Docker with the same hold-open technique and all hit the same fatal assertion: | NF | Test path | Observed result | | --- | --- | --- | | NRF | `/nnrf-nfm/v1/nf-instances` | Crashed with `on_begin_headers: Assertion 'stream' failed`, container exited `139` | | UDM | `/nudm-ueau/v1/imsi-001010000000000/security-information/generate-auth-data` | Crashed with the same assertion, container exited `139` | | UDR | `/nudr-dr/v1/subscription-data/imsi-001010000000000/authentication-data/authentication-subscription` | Crashed with the same assertion; container auto-restarted because of restart policy | | NSSF | `/nnssf-nsselection/v1/network-slice-information` | Crashed with the same assertion, container exited `139` | | BSF | `/nbsf-management/v1/pcfBindings` | Crashed with the same assertion, container exited `139` | | PCF | `/npcf-smpolicycontrol/v1/sm-policies` | Crashed with the same assertion; container auto-restarted because of restart policy | | AMF | `/namf-comm/v1/ue-contexts/1/n1-n2-messages` | Crashed with the same assertion; process aborted with exit `134` | | AUSF | `/nausf-auth/v1/ue-authentications` | Crashed with the same assertion, container exited `139` | | SMF | `/nsmf-pdusession/v1/sm-contexts` | Crashed with the same assertion, container exited `139` | Notes: - `UDR` and `PCF` were initially easy to misread as unaffected because their containers were already back in `running` state when inspected. Their raw NF logs clearly show the same `ogs_pool_id_calloc()` failure and `on_begin_headers` fatal line before the automatic restart. - `UPF` was not part of this impact set because it is not an SBI HTTP/2 NF. - `SCP`, `SEPP`, `CHF`, and `NEF` were not live-tested in this Docker stack because they were not running in the basic deployment, but they use the same shared SBI server code path in source. ### Steps to reproduce 1. Control case on NRF: open a small number of incomplete HTTP/2 requests and confirm the process stays up. ```bash docker start nrf >/dev/null 2>&1 || true docker run --rm --network open5gs \ -v /home/ubuntu/open5gs_277/.audit_tmp:/srv \ node:24-alpine \ sh -lc 'H2_CONNECTIONS=1 H2_STREAMS_PER_CONNECTION=10 H2_HOLD_MS=3000 \ node /srv/h2_hold_open.js nrf.open5gs.org 80 /nnrf-nfm/v1/nf-instances' docker inspect -f '{{.State.Status}} {{.State.ExitCode}}' nrf ``` 2. Malicious case: open many HTTP/2 streams, send request headers, and keep the request bodies unfinished so the server-side stream and request objects stay allocated. ```bash docker start nrf >/dev/null 2>&1 || true docker run --rm --network open5gs \ -v /home/ubuntu/open5gs_277/.audit_tmp:/srv \ node:24-alpine \ sh -lc 'H2_CONNECTIONS=32 H2_STREAMS_PER_CONNECTION=1024 H2_HOLD_MS=12000 \ node /srv/h2_hold_open.js nrf.open5gs.org 80 /nnrf-nfm/v1/nf-instances' docker inspect -f '{{.State.Status}} {{.State.ExitCode}} {{.State.FinishedAt}}' nrf docker logs --tail 20 nrf ``` 3. To validate the cross-NF impact, rerun the same hold-open driver against the other SBI services. During this audit the following targets were used: ```text nrf /nnrf-nfm/v1/nf-instances udm /nudm-ueau/v1/imsi-001010000000000/security-information/generate-auth-data udr /nudr-dr/v1/subscription-data/imsi-001010000000000/authentication-data/authentication-subscription nssf /nnssf-nsselection/v1/network-slice-information bsf /nbsf-management/v1/pcfBindings pcf /npcf-smpolicycontrol/v1/sm-policies amf /namf-comm/v1/ue-contexts/1/n1-n2-messages ausf /nausf-auth/v1/ue-authentications smf /nsmf-pdusession/v1/sm-contexts ``` Raw artifacts from this run were saved under `/home/ubuntu/open5gs_277/.audit_tmp/` including: - `h2_hold_open.js` - `all_nf_hold_open_results.tsv` - `*_hold_open_stress.log` - `*_hold_open_stress.nf.log` ### Logs ```shell Control run on NRF: remoteSettings maxConcurrentStreams=16384 {"authority":"http://nrf.open5gs.org:80","path":"/nnrf-nfm/v1/nf-instances","method":"POST","connections":1,"streamsPerConnection":10,"opened":10,"responses":0,"streamErrors":0,"sessionErrors":0,"holdMs":3000} running 0 Representative malicious run on NRF: {"authority":"http://nrf.open5gs.org:80","path":"/nnrf-nfm/v1/nf-instances","method":"POST","connections":32,"streamsPerConnection":1024,"opened":32768,"responses":0,"streamErrors":31744,"sessionErrors":31,"holdMs":12000} 04/23 02:47:30.323: [sbi] ERROR: ogs_pool_id_calloc() failed (../lib/sbi/nghttp2-server.c:758) 04/23 02:47:30.326: [sbi] FATAL: on_begin_headers: Assertion `stream' failed. (../lib/sbi/nghttp2-server.c:1629) Representative malicious run on PCF showing the auto-restart caveat: 04/23 02:49:28.237: [sbi] ERROR: ogs_pool_id_calloc() failed (../lib/sbi/nghttp2-server.c:758) 04/23 02:49:28.237: [sbi] FATAL: on_begin_headers: Assertion `stream' failed. (../lib/sbi/nghttp2-server.c:1629) Open5GS daemon v2.7.7 04/23 02:49:28.763: [app] INFO: Configuration: '/etc/open5gs/custom/pcf.yaml' (../lib/app/ogs-init.c:144) 04/23 02:49:28.786: [sbi] INFO: nghttp2_server() [http://pcf.open5gs.org]:80 (../lib/sbi/nghttp2-server.c:434) Representative malicious run on AMF: 04/23 02:49:40.733: [sbi] ERROR: ogs_pool_id_calloc() failed (../lib/sbi/nghttp2-server.c:758) 04/23 02:49:40.733: [sbi] FATAL: on_begin_headers: Assertion `stream' failed. (../lib/sbi/nghttp2-server.c:1629) /usr/local/bin/entrypoint.sh: line 10: 7 Aborted (core dumped) open5gs-amfd "${@}" ``` ### Expected behaviour Open5GS should reject excess incomplete or concurrent HTTP/2 requests with a normal transport or application-layer error and should never abort the entire NF process when the shared SBI stream or request pools are exhausted. ### Observed Behaviour Across every live-tested SBI NF in the basic Docker deployment, a client could exhaust the shared SBI stream pool by sending many HTTP/2 requests whose headers were accepted but whose bodies were never finished. Once pool allocation failed, the NF hit `on_begin_headers`' `ogs_assert(stream)` and crashed. Depending on container restart policy, the visible effect was either process exit (`139` or `134`) or a crash immediately followed by automatic restart. ### eNodeB/gNodeB Not required. ### UE Models and versions Not required.
来源⚠️ https://github.com/open5gs/open5gs/issues/4474
用户
 ZiyuLin (UID 93568)
提交2026-05-04 05時06分 (1 月前)
管理2026-05-29 19時15分 (26 days later)
状态已接受
VulDB条目367295 [Open5GS 直到 2.7.7 nghttp2-server.c ogs_pool_id_calloc 拒绝服务]
积分20

Interested in the pricing of exploits?

See the underground prices here!