GitHub Security Advisory: GHSA-44qj-cghf-9p97
Package: github.com/free5gc/smf (GO)
Severity: HIGH (CVSS 7.5)
CWE: CWE-306: Missing Authentication for Critical Function, CWE-617: Reachable Assertion, CWE-862: Missing Authorization
Vulnerable versions: <= 1.4.3
Patched in: unpatched

Summary: free5GC's SMF UPI POST /upi/v1/upNodesLinks exits the SMF process on overlapping UE pools (unauthenticated, reachable Fatalf)

Details:
### Summary
free5GC's SMF mounts the `UPI` management route group without inbound OAuth2 middleware (same root cause as free5gc/free5gc#887). The `POST /upi/v1/upNodesLinks` create-or-update handler accepts attacker-controlled JSON and passes it directly into `UpNodesFromConfiguration()`, which calls `logger.InitLog.Fatalf(...)` on several validation failures. One confirmed path is the UE-IP-pool overlap check: a single unauthenticated POST that adds a new UPF whose pool overlaps an existing UPF terminates the entire SMF process (`docker ps` shows `Exited (1)`), not just the goroutine. This is a stronger sink than free5gc/free5gc#905: that one panics inside the request goroutine and Gin recovers; this one calls `Fatalf` which is `os.Exit(1)`-equivalent and kills the whole SMF process, dropping all of SMF's SBI surface (PDU-session establishment, UE policy lookups, etc.) until the process is restarted.

### 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:47:07Z`)
- SMF endpoint: `http://10.100.200.6:8000`

The broader `UPI` auth gap (#887) lets the unauthenticated POST reach the create/update handler. From there:

Vulnerable handler dispatches into topology parsing:
```
POST /upi/v1/upNodesLinks
 -> UpNodesFromConfiguration()
   -> isOverlap(allUEIPPools)
     -> logger.InitLog.Fatalf("overlap cidr value between UPFs")
```

Code evidence (paths in `free5gc/smf`):
- UPI group mounted WITHOUT auth middleware (preconditions for unauthenticated reachability):
  - `NFs/smf/internal/sbi/server.go:76`
  - `NFs/smf/internal/sbi/server.go:78`
- Create-or-update handler accepts attacker JSON and forwards it to `UpNodesFromConfiguration()`:
  - `NFs/smf/internal/sbi/api_upi.go:60`
  - `NFs/smf/internal/sbi/api_upi.go:72`
- Pool parsing (input from attacker JSON):
  - `NFs/smf/internal/context/user_plane_information.go:413`
- Overlap check that calls `Fatalf`:
  - `NFs/smf/internal/context/user_plane_information.go:479`

The same unauthenticated POST path also reaches sibling `Fatalf` calls for invalid-pool and static-pool-exclusion failures, so this is not a one-off code smell -- it is a class of attacker-reachable `Fatalf` call sites on a single unauthenticated handler:
- `NFs/smf/internal/context/user_plane_information.go:416`
- `NFs/smf/internal/context/user_plane_information.go:424`
- `NFs/smf/internal/context/user_plane_information.go:430`

### PoC
Reproduced end-to-end against the running SMF at `http://10.100.200.6:8000`.

1. Trigger: unauthenticated POST that adds a UPF with a UE pool overlapping the default UPF (`10.60.0.0/16`):
```
curl -i -X POST http://10.100.200.6:8000/upi/v1/upNodesLinks \
  -H 'Content-Type: application/json' \
  --data '{"links":[{"A":"gNB1","B":"UPF-OVERLAP-20260322"}],"upNodes":{"UPF-OVERLAP-20260322":{"typ