6
85
Fork
You've already forked dns
39

Fix Msg.Pack panic: As4 called on IP zero value #917

Open
clfs wants to merge 3 commits from clfs/dns:fix-msg-pack-panic-as4 into main
pull from: clfs/dns:fix-msg-pack-panic-as4
merge into: miekg:main
miekg:main
miekg:miek/26/jun24wo/14
miekg:miek/26/mrt24di/tls
miekg:miek/26/mrt09ma/17
miekg:miek/26/feb15zo/13
miekg:miek/zo-07-dec-25/gslb1
miekg:miek/2025-10-26@1431
miekg:miek/2025-10-18@2017
First-time contributor
Copy link

(*Msg).Pack panics when packing an A record whose address is the netip.Addr zero value.

The panic is reachable by packing a Msg that was unpacked from malformed bytes:

https://go.dev/play/p/Q95WZQjd9ki

packagemainimport("log""codeberg.org/miekg/dns")funcmain(){// header ANCOUNT=1// answer NAME=. TYPE=A CLASS=IN TTL=0 RDLENGTH=0m:=&dns.Msg{Data:[]byte{0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0}}iferr:=m.Unpack();err!=nil{log.Fatalf("Unpack: %v",err)}_=m.Pack()// panic: As4 called on IP zero value}
panic: As4 called on IP zero value
goroutine 1 [running]:
net/netip.Addr.As4(...)
	/usr/local/go-faketime/src/net/netip/netip.go:718
codeberg.org/miekg/dns/internal/pack.A({{0x5de2b8?, 0x0?}, {0x0?}}, {0x13196d08100?, 0x767a78?, 0x13196c6eba8?}, 0x47c68f?)
	/tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/internal/pack/pack.go:152 +0x145
codeberg.org/miekg/dns.(*A).pack(...)
	/tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/zmsg.go:645
codeberg.org/miekg/dns.zpack({0x5e41e0?, 0x13196c04ed0?}, {0x13196d08100?, 0x1c, 0x13196d08100?}, 0x1c?, 0x1c?)
	/tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/zpack.go:32 +0x545
codeberg.org/miekg/dns.packRR({0x5e41e0, 0x13196c04ed0}, {0x13196d08100, 0x1c, 0x1c}, 0xc, 0x13196c6edd0)
	/tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/msg.go:105 +0xf1
codeberg.org/miekg/dns.(*Msg).Pack(0x13196c6ee68)
	/tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/msg.go:230 +0x749
main.main()
	/tmp/sandbox2102939842/prog.go:16 +0xda
Program exited.

This PR adds two fixes:

  1. Guard internal/pack.A with netip.Addr.Is4().
  2. Add a regression test.

I wasn't sure if (*Msg).Unpack should reject the message above, so I left (*Msg).Unpack untouched. If we do want to reject it, I think removing if rdlength == 0 { return rr, nil } in unpackRR could work, but that might hurt performance.

`(*Msg).Pack` panics when packing an A record whose address is the `netip.Addr` zero value. The panic is reachable by packing a `Msg` that was unpacked from malformed bytes: https://go.dev/play/p/Q95WZQjd9ki ```go package main import ( "log" "codeberg.org/miekg/dns" ) func main() { // header ANCOUNT=1 // answer NAME=. TYPE=A CLASS=IN TTL=0 RDLENGTH=0 m := &dns.Msg{Data: []byte{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0}} if err := m.Unpack(); err != nil { log.Fatalf("Unpack: %v", err) } _ = m.Pack() // panic: As4 called on IP zero value } ``` ```plaintext panic: As4 called on IP zero value goroutine 1 [running]: net/netip.Addr.As4(...) /usr/local/go-faketime/src/net/netip/netip.go:718 codeberg.org/miekg/dns/internal/pack.A({{0x5de2b8?, 0x0?}, {0x0?}}, {0x13196d08100?, 0x767a78?, 0x13196c6eba8?}, 0x47c68f?) /tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/internal/pack/pack.go:152 +0x145 codeberg.org/miekg/dns.(*A).pack(...) /tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/zmsg.go:645 codeberg.org/miekg/dns.zpack({0x5e41e0?, 0x13196c04ed0?}, {0x13196d08100?, 0x1c, 0x13196d08100?}, 0x1c?, 0x1c?) /tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/zpack.go:32 +0x545 codeberg.org/miekg/dns.packRR({0x5e41e0, 0x13196c04ed0}, {0x13196d08100, 0x1c, 0x1c}, 0xc, 0x13196c6edd0) /tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/msg.go:105 +0xf1 codeberg.org/miekg/dns.(*Msg).Pack(0x13196c6ee68) /tmp/gopath3234477451/pkg/mod/codeberg.org/miekg/dns@v0.6.83/msg.go:230 +0x749 main.main() /tmp/sandbox2102939842/prog.go:16 +0xda Program exited. ``` This PR adds two fixes: 1. Guard `internal/pack.A` with `netip.Addr.Is4()`. 2. Add a regression test. I wasn't sure if `(*Msg).Unpack` should reject the message above, so I left `(*Msg).Unpack` untouched. If we do want to reject it, I think removing `if rdlength == 0 { return rr, nil }` in `unpackRR` could work, but that might hurt performance.
Some checks are pending
/ test (pull_request) Blocked by required conditions
This pull request can be merged automatically.
Some workflows are waiting to be reviewed.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u fix-msg-pack-panic-as4:clfs-fix-msg-pack-panic-as4
git switch clfs-fix-msg-pack-panic-as4

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff clfs-fix-msg-pack-panic-as4
git switch clfs-fix-msg-pack-panic-as4
git rebase main
git switch main
git merge --ff-only clfs-fix-msg-pack-panic-as4
git switch clfs-fix-msg-pack-panic-as4
git rebase main
git switch main
git merge --no-ff clfs-fix-msg-pack-panic-as4
git switch main
git merge --squash clfs-fix-msg-pack-panic-as4
git switch main
git merge --ff-only clfs-fix-msg-pack-panic-as4
git switch main
git merge clfs-fix-msg-pack-panic-as4
git push origin main
Sign in to join this conversation.
No reviewers
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
miekg/dns!917
Reference in a new issue
miekg/dns
No description provided.
Delete branch "clfs/dns:fix-msg-pack-panic-as4"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?