Skip to content

Commit e13a43f

Browse files
route: use length from message to parse netmask
sizeofSockaddrInet is 16, but first byte of sockaddr specifies the size of the address. 16 works for most cases, except with Netmasks addresses, on Darwin where only the significant bits are in the msg. i.e. ipv4 06 02 00 00 ff ff The above byte sequence is for a sockaddr that is 6 bytes long representing an ipv4 for address that is 255.255.0.0. i.e. ipv6 netmask 0e 1e 00 00 00 00 00 00 ff ff ff ff ff ff 00 00 The above is /48 netmask that should also be parsed as such. Confirmed by using `route monitor`. sources: https://github.com/apple/darwin-xnu/blob/main/bsd/net/route.h https://github.com/apple/darwin-xnu/blob/main/bsd/sys/socket.h#L603
1 parent 35b4aba commit e13a43f

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

route/address.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,20 +170,37 @@ func (a *Inet6Addr) marshal(b []byte) (int, error) {
170170

171171
// parseInetAddr parses b as an internet address for IPv4 or IPv6.
172172
func parseInetAddr(af int, b []byte) (Addr, error) {
173+
const (
174+
off4 = 4 // offset of in_addr
175+
off6 = 8 // offset of in6_addr
176+
)
173177
switch af {
174178
case syscall.AF_INET:
175-
if len(b) < sizeofSockaddrInet {
179+
if len(b) < (off4+1) || len(b) < int(b[0]) {
176180
return nil, errInvalidAddr
177181
}
182+
sockAddrLen := int(b[0])
178183
a := &Inet4Addr{}
179-
copy(a.IP[:], b[4:8])
184+
n := off4 + 4
185+
if sockAddrLen < n {
186+
n = sockAddrLen
187+
}
188+
copy(a.IP[:], b[off4:n])
180189
return a, nil
181190
case syscall.AF_INET6:
182-
if len(b) < sizeofSockaddrInet6 {
191+
if len(b) < (off6+1) || len(b) < int(b[0]) {
183192
return nil, errInvalidAddr
184193
}
185-
a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
186-
copy(a.IP[:], b[8:24])
194+
sockAddrLen := int(b[0])
195+
n := off6 + 16
196+
if sockAddrLen < n {
197+
n = sockAddrLen
198+
}
199+
a := &Inet6Addr{}
200+
if sockAddrLen == sizeofSockaddrInet6 {
201+
a.ZoneID = int(nativeEndian.Uint32(b[24:28]))
202+
}
203+
copy(a.IP[:], b[off6:n])
187204
if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
188205
// KAME based IPv6 protocol stack usually
189206
// embeds the interface index in the

0 commit comments

Comments
 (0)