mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
internal/routebsd: fix parsing network address of length zero
This applies CL 646555 from the net repository to this copy. For #70528 Change-Id: Ib7e23accfa3f278392e7bdca6f8544b8f1395e7e Reviewed-on: https://go-review.googlesource.com/c/go/+/646676 Reviewed-by: Damien Neil <dneil@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> TryBot-Bypass: Ian Lance Taylor <iant@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
b7c9cdd53c
commit
f6ea0621d2
@ -104,33 +104,40 @@ func parseInetAddr(af int, b []byte) (Addr, error) {
|
|||||||
const (
|
const (
|
||||||
off4 = 4 // offset of in_addr
|
off4 = 4 // offset of in_addr
|
||||||
off6 = 8 // offset of in6_addr
|
off6 = 8 // offset of in6_addr
|
||||||
|
ipv4Len = 4 // length of IPv4 address in bytes
|
||||||
|
ipv6Len = 16 // length of IPv6 address in bytes
|
||||||
)
|
)
|
||||||
switch af {
|
switch af {
|
||||||
case syscall.AF_INET:
|
case syscall.AF_INET:
|
||||||
if len(b) < (off4+1) || len(b) < int(b[0]) || b[0] == 0 {
|
if len(b) < (off4+1) || len(b) < int(b[0]) {
|
||||||
return nil, errInvalidAddr
|
return nil, errInvalidAddr
|
||||||
}
|
}
|
||||||
sockAddrLen := int(b[0])
|
sockAddrLen := int(b[0])
|
||||||
var ip [4]byte
|
var ip [ipv4Len]byte
|
||||||
n := off4 + 4
|
if sockAddrLen != 0 {
|
||||||
|
// Calculate how many bytes of the address to copy:
|
||||||
|
// either full IPv4 length or the available length.
|
||||||
|
n := off4 + ipv4Len
|
||||||
if sockAddrLen < n {
|
if sockAddrLen < n {
|
||||||
n = sockAddrLen
|
n = sockAddrLen
|
||||||
}
|
}
|
||||||
copy(ip[:], b[off4:n])
|
copy(ip[:], b[off4:n])
|
||||||
|
}
|
||||||
a := &InetAddr{
|
a := &InetAddr{
|
||||||
IP: netip.AddrFrom4(ip),
|
IP: netip.AddrFrom4(ip),
|
||||||
}
|
}
|
||||||
return a, nil
|
return a, nil
|
||||||
case syscall.AF_INET6:
|
case syscall.AF_INET6:
|
||||||
if len(b) < (off6+1) || len(b) < int(b[0]) || b[0] == 0 {
|
if len(b) < (off6+1) || len(b) < int(b[0]) {
|
||||||
return nil, errInvalidAddr
|
return nil, errInvalidAddr
|
||||||
}
|
}
|
||||||
|
var ip [ipv6Len]byte
|
||||||
sockAddrLen := int(b[0])
|
sockAddrLen := int(b[0])
|
||||||
n := off6 + 16
|
if sockaddrLen != 0 {
|
||||||
|
n := off6 + ipv6Len
|
||||||
if sockAddrLen < n {
|
if sockAddrLen < n {
|
||||||
n = sockAddrLen
|
n = sockAddrLen
|
||||||
}
|
}
|
||||||
var ip [16]byte
|
|
||||||
copy(ip[:], b[off6:n])
|
copy(ip[:], b[off6:n])
|
||||||
if ip[0] == 0xfe && ip[1]&0xc0 == 0x80 || ip[0] == 0xff && (ip[1]&0x0f == 0x01 || ip[1]&0x0f == 0x02) {
|
if ip[0] == 0xfe && ip[1]&0xc0 == 0x80 || ip[0] == 0xff && (ip[1]&0x0f == 0x01 || ip[1]&0x0f == 0x02) {
|
||||||
// KAME based IPv6 protocol stack usually
|
// KAME based IPv6 protocol stack usually
|
||||||
@ -142,6 +149,7 @@ func parseInetAddr(af int, b []byte) (Addr, error) {
|
|||||||
ip[2], ip[3] = 0, 0
|
ip[2], ip[3] = 0, 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// The kernel can provide an integer zone ID.
|
// The kernel can provide an integer zone ID.
|
||||||
// We ignore it.
|
// We ignore it.
|
||||||
a := &InetAddr{
|
a := &InetAddr{
|
||||||
@ -197,11 +205,11 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
|
|||||||
switch {
|
switch {
|
||||||
case b[0] == syscall.SizeofSockaddrInet6:
|
case b[0] == syscall.SizeofSockaddrInet6:
|
||||||
a := &InetAddr{
|
a := &InetAddr{
|
||||||
IP: netip.AddrFrom16([16]byte(b[off6:off6+16])),
|
IP: netip.AddrFrom16([16]byte(b[off6 : off6+16])),
|
||||||
}
|
}
|
||||||
return int(b[0]), a, nil
|
return int(b[0]), a, nil
|
||||||
case af == syscall.AF_INET6:
|
case af == syscall.AF_INET6:
|
||||||
var ab[16]byte
|
var ab [16]byte
|
||||||
if l-1 < off6 {
|
if l-1 < off6 {
|
||||||
copy(ab[:], b[1:l])
|
copy(ab[:], b[1:l])
|
||||||
} else {
|
} else {
|
||||||
@ -213,7 +221,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
|
|||||||
return int(b[0]), a, nil
|
return int(b[0]), a, nil
|
||||||
case b[0] == syscall.SizeofSockaddrInet4:
|
case b[0] == syscall.SizeofSockaddrInet4:
|
||||||
a := &InetAddr{
|
a := &InetAddr{
|
||||||
IP: netip.AddrFrom4([4]byte(b[off4:off4+4])),
|
IP: netip.AddrFrom4([4]byte(b[off4 : off4+4])),
|
||||||
}
|
}
|
||||||
return int(b[0]), a, nil
|
return int(b[0]), a, nil
|
||||||
default: // an old fashion, AF_UNSPEC or unknown means AF_INET
|
default: // an old fashion, AF_UNSPEC or unknown means AF_INET
|
||||||
@ -251,16 +259,12 @@ func parseAddrs(attrs uint, b []byte) ([]Addr, error) {
|
|||||||
}
|
}
|
||||||
b = b[l:]
|
b = b[l:]
|
||||||
case syscall.AF_INET, syscall.AF_INET6:
|
case syscall.AF_INET, syscall.AF_INET6:
|
||||||
// #70528: if the sockaddrlen is 0, no address to parse inside,
|
|
||||||
// skip over the record.
|
|
||||||
if b[0] > 0 {
|
|
||||||
af = int(b[1])
|
af = int(b[1])
|
||||||
a, err := parseInetAddr(af, b)
|
a, err := parseInetAddr(af, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
as[i] = a
|
as[i] = a
|
||||||
}
|
|
||||||
l := roundup(int(b[0]))
|
l := roundup(int(b[0]))
|
||||||
if len(b) < l {
|
if len(b) < l {
|
||||||
return nil, errMessageTooShort
|
return nil, errMessageTooShort
|
||||||
|
@ -108,7 +108,7 @@ var parseAddrsOnDarwinLittleEndianTests = []parseAddrsOnDarwinTest{
|
|||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||||
},
|
},
|
||||||
[]Addr{
|
[]Addr{
|
||||||
nil,
|
&InetAddr{IP: netip.AddrFrom16([16]byte{})},
|
||||||
&InetAddr{IP: netip.AddrFrom16([16]byte{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff})},
|
&InetAddr{IP: netip.AddrFrom16([16]byte{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff})},
|
||||||
&InetAddr{IP: netip.AddrFrom16([16]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff})},
|
&InetAddr{IP: netip.AddrFrom16([16]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff})},
|
||||||
nil,
|
nil,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user