CVE-2026-44328 - free5GC's SMF UPI DELETE /upi/v1/upNodesLinks/{ref} panics on AN-node deletion v
CVE-2026-44328 - free5GC's SMF UPI DELETE /upi/v1/upNodesLinks/{ref} panics on AN-node deletion v
GHSA-p9mg-74mg-cwwr HIGH go/github.com/free5gc/smf
CVE: CVE-2026-44328
Summary
free5GC's SMF mounts the UPI management route group without inbound OAuth2 middleware (same root cause as the broader UPI auth gap reported in free5gc/free5gc#887). On top of that, the DELETE /upi/v1/upNodesLinks/{upNodeRef} handler unconditionally dereferences upNode.UPF after the type-guarded async release, even though AN-typed nodes are constructed without a UPF object. As a result, a single unauthenticated DELETE /upi/v1/upNodesLinks/gNB1 request crashes the handler with a nil-pointer panic AND mutates the in-memory user-plane topology before panicking (the UpNodeDelete(upNodeRef) line runs first). This is an unauthenticated, state-mutating panic-DoS sink that an off-path network attacker can trigger by name against any AN entry.
Details
Validated against the SMF container in the official Docker compose lab.
- Source repo tag:
v4.2.1 - Running Docker image:
free5gc/smf:v4.2.1 - Runtime SMF commit:
8385c00a - Docker validation date: 2026-03-22 local (container log timestamp
2026-03-21T23:43:17Z) - SMF endpoint:
http://10.100.200.6:8000
Control comparison on the same SMF instance:
GET /nsmf-oam/v1/(no token) ->401 UnauthorizedDELETE /upi/v1/upNodesLinks/gNB1(no token) ->500 Internal Server Error(panic)
The sibling nsmf-oam returning 401 proves OAuth middleware IS wired in for other SMF route groups; the UPI group specifically is mounted without it.
Vulnerable handler logic (paths in free5gc/smf):
// NFs/smf/internal/sbi/api_upi.go:94..99
if upNode.Type == smf_context.UPNODE_UPF {
go s.Processor().ReleaseAllResourcesOfUPF(upNode.UPF)
}
upi.UpNodeDelete(upNodeRef)
upNode.UPF.CancelAssociation() // <-- panics for AN-typed nodes; nil UPFThe Type == UPNODE_UPF guard only protects the asynchronous ReleaseAllResourcesOfUPF call. After that, UpNodeDelete(upNodeRef) runs unconditionally (so the topology mutation lands first), and then upNode.UPF.CancelAssociation() is called uncon
📌 来源: GitHub-Advisory | 🆔 CVE-2026-44328 | 📅 2026-05-08