mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-18 08:16:39 +00:00
Validate prefix length bounds in DecodePrefix
This commit is contained in:
@@ -26,14 +26,22 @@ func DecodePrefix(b []byte) (netip.Prefix, error) {
|
|||||||
case 5:
|
case 5:
|
||||||
var ip4 [4]byte
|
var ip4 [4]byte
|
||||||
copy(ip4[:], b)
|
copy(ip4[:], b)
|
||||||
return netip.PrefixFrom(netip.AddrFrom4(ip4), int(b[len(b)-1])), nil
|
bits := int(b[len(b)-1])
|
||||||
|
if bits > 32 {
|
||||||
|
return netip.Prefix{}, fmt.Errorf("invalid IPv4 prefix length %d (max 32)", bits)
|
||||||
|
}
|
||||||
|
return netip.PrefixFrom(netip.AddrFrom4(ip4), bits), nil
|
||||||
case 17:
|
case 17:
|
||||||
var ip6 [16]byte
|
var ip6 [16]byte
|
||||||
copy(ip6[:], b)
|
copy(ip6[:], b)
|
||||||
addr := netip.AddrFrom16(ip6).Unmap()
|
addr := netip.AddrFrom16(ip6).Unmap()
|
||||||
bits := int(b[len(b)-1])
|
bits := int(b[len(b)-1])
|
||||||
if addr.Is4() && bits > 32 {
|
if addr.Is4() {
|
||||||
bits = 32
|
if bits > 32 {
|
||||||
|
bits = 32
|
||||||
|
}
|
||||||
|
} else if bits > 128 {
|
||||||
|
return netip.Prefix{}, fmt.Errorf("invalid IPv6 prefix length %d (max 128)", bits)
|
||||||
}
|
}
|
||||||
return netip.PrefixFrom(addr, bits), nil
|
return netip.PrefixFrom(addr, bits), nil
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -110,6 +110,22 @@ func TestDecodePrefixInvalidLength(t *testing.T) {
|
|||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecodePrefixInvalidBits(t *testing.T) {
|
||||||
|
// v4 with bits > 32
|
||||||
|
b := []byte{10, 0, 0, 1, 33}
|
||||||
|
_, err := DecodePrefix(b)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "invalid IPv4 prefix length 33")
|
||||||
|
|
||||||
|
// v6 with bits > 128
|
||||||
|
b = make([]byte, 17)
|
||||||
|
b[0] = 0xfd
|
||||||
|
b[16] = 129
|
||||||
|
_, err = DecodePrefix(b)
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "invalid IPv6 prefix length 129")
|
||||||
|
}
|
||||||
|
|
||||||
func TestDecodePrefixUnmapsV6Input(t *testing.T) {
|
func TestDecodePrefixUnmapsV6Input(t *testing.T) {
|
||||||
// If someone encodes a v4-mapped v6 as 17 bytes, decode should unmap it
|
// If someone encodes a v4-mapped v6 as 17 bytes, decode should unmap it
|
||||||
// and clamp the prefix length to 32 for v4
|
// and clamp the prefix length to 32 for v4
|
||||||
|
|||||||
Reference in New Issue
Block a user