mirror of
https://github.com/golang/go
synced 2024-11-18 11:14:39 -07:00
syscall: fix alignment check for link-layer information on BSD variants
When link-layer information is wrapped with sockaddr_dl, we need to follow the len field of sockaddr_dl. When link-layer information is naked, we need to use the length of whole link-layer information. Fixes #12641. Change-Id: I4d377f64cbab1760b993fc55c719288616042bbb Reviewed-on: https://go-review.googlesource.com/14939 Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
81fada52a6
commit
707b619c3a
@ -44,6 +44,9 @@ func rsaAlignOf(salen int) int {
|
||||
|
||||
// parseSockaddrLink parses b as a datalink socket address.
|
||||
func parseSockaddrLink(b []byte) (*SockaddrDatalink, error) {
|
||||
if len(b) < 8 {
|
||||
return nil, EINVAL
|
||||
}
|
||||
sa, _, err := parseLinkLayerAddr(b[4:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -77,16 +80,16 @@ func parseLinkLayerAddr(b []byte) (*SockaddrDatalink, int, error) {
|
||||
Slen byte
|
||||
}
|
||||
lla := (*linkLayerAddr)(unsafe.Pointer(&b[0]))
|
||||
l := rsaAlignOf(int(4 + lla.Nlen + lla.Alen + lla.Slen))
|
||||
l := 4 + int(lla.Nlen) + int(lla.Alen) + int(lla.Slen)
|
||||
if len(b) < l {
|
||||
return nil, 0, EINVAL
|
||||
}
|
||||
b = b[4:]
|
||||
sa := &SockaddrDatalink{Type: lla.Type, Nlen: lla.Nlen, Alen: lla.Alen, Slen: lla.Slen}
|
||||
for i := 0; len(sa.Data) > i && i < int(lla.Nlen+lla.Alen+lla.Slen); i++ {
|
||||
for i := 0; len(sa.Data) > i && i < l-4; i++ {
|
||||
sa.Data[i] = int8(b[i])
|
||||
}
|
||||
return sa, l, nil
|
||||
return sa, rsaAlignOf(l), nil
|
||||
}
|
||||
|
||||
// parseSockaddrInet parses b as an internet socket address.
|
||||
|
@ -119,6 +119,41 @@ func TestRouteMonitor(t *testing.T) {
|
||||
<-tmo
|
||||
}
|
||||
|
||||
var parseInterfaceMessageTests = []*syscall.InterfaceMessage{
|
||||
// with link-layer address
|
||||
{
|
||||
Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP},
|
||||
Data: []uint8{
|
||||
0x11, 0x12, 0x2, 0x0, 0x6, 0x3, 0x6, 0x0,
|
||||
0x77, 0x6d, 0x31, 0x01, 0x23, 0x45, 0xab, 0xcd,
|
||||
0xef, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
},
|
||||
},
|
||||
// without link-layer address
|
||||
{
|
||||
Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP},
|
||||
Data: []uint8{
|
||||
0xe, 0x12, 0x4, 0x0, 0xf5, 0x6, 0x0, 0x0,
|
||||
0x70, 0x66, 0x6c, 0x6f, 0x67, 0x30, 0x0, 0x0,
|
||||
},
|
||||
},
|
||||
// no data
|
||||
{
|
||||
Header: syscall.IfMsghdr{Version: syscall.RTM_VERSION, Addrs: syscall.RTA_IFP},
|
||||
Data: []uint8{
|
||||
0x8, 0xa, 0xb, 0xc, 0xd, 0x0, 0x0, 0x0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestParseInterfaceMessage(t *testing.T) {
|
||||
for i, tt := range parseInterfaceMessageTests {
|
||||
if _, err := syscall.ParseRoutingSockaddr(tt); err != nil {
|
||||
t.Errorf("#%d: %v", i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type addrFamily byte
|
||||
|
||||
func (f addrFamily) String() string {
|
||||
|
Loading…
Reference in New Issue
Block a user