Skip to content

netutils: do not panic on a non-IPv4 MD5 address on OpenBSD - #3613

Merged
fujita merged 1 commit into
osrg:masterfrom
Dev-next-gen:openbsd-md5-non-ipv4
Sep 16, 2026
Merged

fujita merged 1 commit into
osrg:masterfrom
Dev-next-gen:openbsd-md5-non-ipv4

Conversation

@Dev-next-gen

Copy link
Copy Markdown
Contributor

On OpenBSD, SetTCPMD5SigSockopt installs the MD5 key through PF_KEY, and rfkeyRequest builds the sockaddr_in for each end with newSockaddrIn. That function does net.ParseIP(addr).To4() and indexes the result without checking it, so any address that is not a plain IPv4 address panics with index out of range [3] with length 0.

The server passes it two kinds of such addresses: an IPv6 neighbor with auth-password (through addAuthKeysToListeners), and a dynamic neighbor whose peer group has a password, where the prefix string such as 10.0.0.0/24 is passed as the address. Either one crashes gobgpd, even though every caller already logs a "failed to set md5" warning when an error comes back. With this change, newSockaddrIn returns an error when the address has no IPv4 form, and rfkeyRequest returns it before anything is written to the PF_KEY socket. newSockaddrIn is unexported and lives under internal/, so changing its signature affects nothing outside this file, and the empty-address case works as before.

CI only cross-builds openbsd, and I have no OpenBSD machine, so here is how I checked it. The new test is //go:build openbsd. GOOS=openbsd go vet and GOOS=openbsd go test -c both succeed. To run it, I copied sockopt_openbsd.go and the test into a scratch package on Linux under neutral file names with the build tag removed, next to the other untagged netutils files. The code under test is plain Go and fails before it touches the socket. With the current sockopt_openbsd.go, TestSaAddRejectsNonIPv4Address panics in newSockaddrIn (called from rfkeyRequest via saAdd). With the patched file, the test passes. GOOS=openbsd, freebsd and linux go build ./... are also clean.

Found by a defect-hunting pipeline I build and run (Dev-next-gen), using Claude Code with Anthropic's Claude Opus 5.

On OpenBSD, SetTCPMD5SigSockopt installs the key through PF_KEY, and
rfkeyRequest builds the sockaddr_in for each end with newSockaddrIn.
newSockaddrIn calls net.ParseIP(addr).To4() and indexes the result
without checking it, so any address that is not a plain IPv4 address
makes it index a nil slice and panic.

The server hands it two such addresses. A neighbor with an IPv6
address and an auth password reaches it through
addAuthKeysToListeners, and a dynamic neighbor whose peer group has a
password reaches it with the prefix string, e.g. "10.0.0.0/24". Either
configuration takes gobgpd down instead of logging the "failed to set
md5" warning the callers already have for this case.

Return an error from newSockaddrIn when the address has no IPv4 form,
and pass it up from rfkeyRequest before anything is written to the
PF_KEY socket.
@fujita
fujita merged commit 452e7f4 into osrg:master Sep 16, 2026
42 checks passed
@fujita

fujita commented Sep 16, 2026

Copy link
Copy Markdown
Member

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants