Netstack: Check that the multicast address matches the endpoint protocol.

Reported-by: syzbot+a72cb94d1b5a6f5f0e11@syzkaller.appspotmail.com
PiperOrigin-RevId: 467975743
This commit is contained in:
Lucas Manning
2022-08-16 11:18:51 -07:00
committed by gVisor bot
parent 2bb73c7bd7
commit b195ca54f3
4 changed files with 56 additions and 3 deletions
+7 -2
View File
@@ -45,8 +45,13 @@ import (
"gvisor.dev/gvisor/pkg/waiter"
)
// Using header.IPv4AddressSize would cause an import cycle.
const ipv4AddressSize = 4
// Using the header package here would cause an import cycle.
const (
ipv4AddressSize = 4
ipv4ProtocolNumber = 0x0800
ipv6AddressSize = 16
ipv6ProtocolNumber = 0x86dd
)
// Errors related to Subnet
var (
+1
View File
@@ -120,6 +120,7 @@ go_test(
"//pkg/tcpip/tests/utils",
"//pkg/tcpip/testutil",
"//pkg/tcpip/transport/icmp",
"//pkg/tcpip/transport/raw",
"//pkg/tcpip/transport/udp",
"//pkg/waiter",
"@com_github_google_go_cmp//cmp:go_default_library",
@@ -32,6 +32,7 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/tests/utils"
"gvisor.dev/gvisor/pkg/tcpip/testutil"
"gvisor.dev/gvisor/pkg/tcpip/transport/icmp"
"gvisor.dev/gvisor/pkg/tcpip/transport/raw"
"gvisor.dev/gvisor/pkg/tcpip/transport/udp"
"gvisor.dev/gvisor/pkg/waiter"
)
@@ -777,3 +778,49 @@ func TestAddMembershipInterfacePrecedence(t *testing.T) {
t.Fatalf("ep.SetSockOpt(&%#v): %s", addOpt, err)
}
}
func TestMismatchedMulticastAddressAndProtocol(t *testing.T) {
const nicID = 1
// MulticastAddr is IPv4, but proto is IPv6.
multicastAddr := tcpip.Address("\xe0\x01\x02\x03")
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol},
TransportProtocols: []stack.TransportProtocolFactory{icmp.NewProtocol6},
RawFactory: raw.EndpointFactory{},
})
e := channel.New(0, defaultMTU, "")
defer e.Close()
if err := s.CreateNIC(nicID, e); err != nil {
t.Fatalf("CreateNIC(%d, _): %s", nicID, err)
}
protoAddr := tcpip.ProtocolAddress{Protocol: header.IPv4ProtocolNumber, AddressWithPrefix: utils.Ipv4Addr}
if err := s.AddProtocolAddress(nicID, protoAddr, stack.AddressProperties{}); err != nil {
t.Fatalf("AddProtocolAddress(%d, %+v, {}): %s", nicID, protoAddr, err)
}
var wq waiter.Queue
ep, err := s.NewRawEndpoint(header.ICMPv6ProtocolNumber, header.IPv6ProtocolNumber, &wq, false)
if err != nil {
t.Fatalf("NewEndpoint(%d, %d, _): %s", udp.ProtocolNumber, header.IPv6ProtocolNumber, err)
}
defer ep.Close()
bindAddr := tcpip.FullAddress{Port: utils.LocalPort}
if err := ep.Bind(bindAddr); err != nil {
t.Fatalf("ep.Bind(%#v): %s", bindAddr, err)
}
memOpt := tcpip.MembershipOption{
MulticastAddr: multicastAddr,
NIC: 0,
InterfaceAddr: utils.Ipv4Addr.Address,
}
// Add membership should succeed when the interface index is specified,
// even if a bad interface address is specified.
addOpt := tcpip.AddMembershipOption(memOpt)
expErr := &tcpip.ErrInvalidOptionValue{}
if err := ep.SetSockOpt(&addOpt); err != expErr {
t.Fatalf("ep.SetSockOpt(&%#v): want %q, got %q", addOpt, expErr, err)
}
}
@@ -915,7 +915,7 @@ func (e *Endpoint) SetSockOpt(opt tcpip.SettableSocketOption) tcpip.Error {
e.multicastAddr = addr
case *tcpip.AddMembershipOption:
if !header.IsV4MulticastAddress(v.MulticastAddr) && !header.IsV6MulticastAddress(v.MulticastAddr) {
if !(header.IsV4MulticastAddress(v.MulticastAddr) && e.netProto == header.IPv4ProtocolNumber) && !(header.IsV6MulticastAddress(v.MulticastAddr) && e.netProto == header.IPv6ProtocolNumber) {
return &tcpip.ErrInvalidOptionValue{}
}