From 8756ebc3b406e2f8ea43360902d8a6dfff391236 Mon Sep 17 00:00:00 2001 From: Konstantin Bogomolov Date: Fri, 11 Nov 2022 09:17:30 -0800 Subject: [PATCH] Netstack: Check address matches the endpoint protocol for IP_DROP_MEMBERSHIP According to syzkaller report, the setsockopt option used was 0x24, which matches with IP_DROP_MEMBERSHIP for which we did not have the equivalent check that we had for IP_ADD_MEMBERSHIP. Reported-by: syzbot+923097b958e5b74950d1@syzkaller.appspotmail.com PiperOrigin-RevId: 487840922 --- pkg/tcpip/tests/integration/multicast_broadcast_test.go | 7 ++++++- pkg/tcpip/transport/internal/network/endpoint.go | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/pkg/tcpip/tests/integration/multicast_broadcast_test.go b/pkg/tcpip/tests/integration/multicast_broadcast_test.go index 57416b607..9a1b3fdcf 100644 --- a/pkg/tcpip/tests/integration/multicast_broadcast_test.go +++ b/pkg/tcpip/tests/integration/multicast_broadcast_test.go @@ -817,11 +817,16 @@ func TestMismatchedMulticastAddressAndProtocol(t *testing.T) { InterfaceAddr: utils.Ipv4Addr.Address, } - // Add membership should succeed when the interface index is specified, + // Add/remove 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) } + + removeOpt := tcpip.RemoveMembershipOption(memOpt) + if err := ep.SetSockOpt(&removeOpt); err != expErr { + t.Fatalf("ep.SetSockOpt(&%#v): want %q, got %q", addOpt, expErr, err) + } } diff --git a/pkg/tcpip/transport/internal/network/endpoint.go b/pkg/tcpip/transport/internal/network/endpoint.go index 2f6acc781..87f45d3df 100644 --- a/pkg/tcpip/transport/internal/network/endpoint.go +++ b/pkg/tcpip/transport/internal/network/endpoint.go @@ -951,7 +951,7 @@ func (e *Endpoint) SetSockOpt(opt tcpip.SettableSocketOption) tcpip.Error { e.multicastMemberships[memToInsert] = struct{}{} case *tcpip.RemoveMembershipOption: - 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{} }