From f83bbaf3af8d938bd15429254bbbdcc6d4b42144 Mon Sep 17 00:00:00 2001 From: Mauri de Souza Meneguzzo Date: Wed, 1 Nov 2023 23:19:39 +0000 Subject: [PATCH] net/netip: allow only valid prefix digits in ParsePrefix The prefix bits for a call to ParsePrefix are passed raw to strconv.Atoi, this means that it can accept +- signs as well as leading zeroes, which are not allowed prefix values following RFC 4632 Section 3.1 and RFC 4291 Section 2.3. Validate non-digit characters as well as leading zeroes and return an error accordingly. Fixes #63850 Change-Id: I412a7e1cecc6ee9ea1582d4b04cb40d79ee714f1 GitHub-Last-Rev: 462d97fc5f412e18376356dbc10b63711c084144 GitHub-Pull-Request: golang/go#63859 Reviewed-on: https://go-review.googlesource.com/c/go/+/538860 Reviewed-by: Heschi Kreinick Reviewed-by: Tobias Klauser Reviewed-by: Cherry Mui Reviewed-by: Brad Fitzpatrick LUCI-TryBot-Result: Go LUCI --- src/net/netip/netip.go | 6 ++++++ src/net/netip/netip_test.go | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/net/netip/netip.go b/src/net/netip/netip.go index 99cb754fae..46f466c076 100644 --- a/src/net/netip/netip.go +++ b/src/net/netip/netip.go @@ -1309,6 +1309,12 @@ func ParsePrefix(s string) (Prefix, error) { } bitsStr := s[i+1:] + + // strconv.Atoi accepts a leading sign and leading zeroes, but we don't want that. + if len(bitsStr) > 1 && (bitsStr[0] < '1' || bitsStr[0] > '9') { + return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): bad bits after slash: " + strconv.Quote(bitsStr)) + } + bits, err := strconv.Atoi(bitsStr) if err != nil { return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): bad bits after slash: " + strconv.Quote(bitsStr)) diff --git a/src/net/netip/netip_test.go b/src/net/netip/netip_test.go index 39893e0f6d..36e57ce171 100644 --- a/src/net/netip/netip_test.go +++ b/src/net/netip/netip_test.go @@ -1456,7 +1456,7 @@ func TestParsePrefixError(t *testing.T) { }, { prefix: "1.1.1.0/-1", - errstr: "out of range", + errstr: "bad bits", }, { prefix: "1.1.1.0/33", @@ -1475,6 +1475,22 @@ func TestParsePrefixError(t *testing.T) { prefix: "2001:db8::%a/32", errstr: "zones cannot be present", }, + { + prefix: "1.1.1.0/+32", + errstr: "bad bits", + }, + { + prefix: "1.1.1.0/-32", + errstr: "bad bits", + }, + { + prefix: "1.1.1.0/032", + errstr: "bad bits", + }, + { + prefix: "1.1.1.0/0032", + errstr: "bad bits", + }, } for _, test := range tests { t.Run(test.prefix, func(t *testing.T) {