From 7f08016fb8be5d917246c3d66ce8dec27378d459 Mon Sep 17 00:00:00 2001 From: Kevin Krakauer Date: Tue, 31 Oct 2023 21:15:06 -0700 Subject: [PATCH] iptables: check revision numbers and support owner matcher v1 This change also replaces use of kernel.Task with a narrower type (IDMapper) in preparation for a follow-up CL. PiperOrigin-RevId: 578387814 --- pkg/abi/linux/netfilter.go | 28 +++- pkg/sentry/socket/netfilter/BUILD | 14 +- pkg/sentry/socket/netfilter/extensions.go | 48 ++++-- pkg/sentry/socket/netfilter/ipv4.go | 5 +- pkg/sentry/socket/netfilter/ipv6.go | 5 +- pkg/sentry/socket/netfilter/istio_blob | Bin 0 -> 5688 bytes pkg/sentry/socket/netfilter/netfilter.go | 19 ++- pkg/sentry/socket/netfilter/netfilter_test.go | 56 +++++++ pkg/sentry/socket/netfilter/owner_matcher.go | 16 +- .../socket/netfilter/owner_matcher_v1.go | 152 ++++++++++++++++++ pkg/sentry/socket/netfilter/tcp_matcher.go | 11 +- pkg/sentry/socket/netfilter/udp_matcher.go | 11 +- pkg/sentry/socket/netstack/netstack.go | 4 +- 13 files changed, 328 insertions(+), 41 deletions(-) create mode 100755 pkg/sentry/socket/netfilter/istio_blob create mode 100644 pkg/sentry/socket/netfilter/netfilter_test.go create mode 100644 pkg/sentry/socket/netfilter/owner_matcher_v1.go diff --git a/pkg/abi/linux/netfilter.go b/pkg/abi/linux/netfilter.go index 1470a55788..3c5f40c1ef 100644 --- a/pkg/abi/linux/netfilter.go +++ b/pkg/abi/linux/netfilter.go @@ -633,8 +633,8 @@ const ( XT_UDP_INV_MASK = 0x03 ) -// IPTOwnerInfo holds data for matching packets with owner. It corresponds -// to struct ipt_owner_info in libxt_owner.c of iptables binary. +// IPTOwnerInfo holds data for matching packets with the owner v0 matcher. It +// corresponds to struct ipt_owner_info in libxt_owner.c of iptables binary. // // +marshal type IPTOwnerInfo struct { @@ -661,11 +661,29 @@ type IPTOwnerInfo struct { Invert uint8 `marshal:"unaligned"` } -// SizeOfIPTOwnerInfo is the size of an XTOwnerMatchInfo. +// SizeOfIPTOwnerInfo is the size of an IPTOwnerInfo. const SizeOfIPTOwnerInfo = 34 -// Flags in IPTOwnerInfo.Match. Corresponding constants are in -// include/uapi/linux/netfilter/xt_owner.h. +// XTOwnerMatchInfo holds data for matching packets with the owner v1 matcher. +// It corresponds to struct xt_owner_match_info in +// include/uapi/linux/netfilter/xt_owner.h +// +// +marshal +type XTOwnerMatchInfo struct { + UIDMin uint32 + UIDMax uint32 + GIDMin uint32 + GIDMax uint32 + Match uint8 + Invert uint8 + _ [2]byte +} + +// SizeOfXTOwnerMatchInfo is the size of an XTOwnerMatchInfo. +const SizeOfXTOwnerMatchInfo = 20 + +// Flags in IPTOwnerInfo.Match and XTOwnerMatchInfo.Match. Corresponding +// constants are in include/uapi/linux/netfilter/xt_owner.h. const ( // Match the UID of the packet. XT_OWNER_UID = 1 << 0 diff --git a/pkg/sentry/socket/netfilter/BUILD b/pkg/sentry/socket/netfilter/BUILD index 09bb4de187..edb5007b8c 100644 --- a/pkg/sentry/socket/netfilter/BUILD +++ b/pkg/sentry/socket/netfilter/BUILD @@ -1,4 +1,4 @@ -load("//tools:defs.bzl", "go_library") +load("//tools:defs.bzl", "go_library", "go_test") package( default_applicable_licenses = ["//:license"], @@ -13,6 +13,7 @@ go_library( "ipv6.go", "netfilter.go", "owner_matcher.go", + "owner_matcher_v1.go", "targets.go", "tcp_matcher.go", "udp_matcher.go", @@ -35,3 +36,14 @@ go_library( "//pkg/tcpip/stack", ], ) + +go_test( + name = "netfilter_test", + srcs = ["netfilter_test.go"], + embedsrcs = ["istio_blob"], + library = ":netfilter", + deps = [ + "//pkg/sentry/kernel/auth", + "//pkg/tcpip/stack", + ], +) diff --git a/pkg/sentry/socket/netfilter/extensions.go b/pkg/sentry/socket/netfilter/extensions.go index 7606d2bbba..56ced4ae69 100644 --- a/pkg/sentry/socket/netfilter/extensions.go +++ b/pkg/sentry/socket/netfilter/extensions.go @@ -19,45 +19,65 @@ import ( "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/bits" - "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/syserr" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/stack" ) -// matchMaker knows how to (un)marshal the matcher named name(). +// matchMaker knows how to (un)marshal the matcher named name(). UPDATE THIS type matchMaker interface { // name is the matcher name as stored in the xt_entry_match struct. name() string + // revision is the match revision as stored in the xt_entry_match + // struct. + revision() uint8 + // marshal converts from a stack.Matcher to an ABI struct. marshal(matcher matcher) []byte // unmarshal converts from the ABI matcher struct to an // stack.Matcher. - unmarshal(task *kernel.Task, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) + unmarshal(mapper IDMapper, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) +} + +type matchKey struct { + name string + revision uint8 +} + +func key(mm matchMaker) matchKey { + return matchKey{ + name: mm.name(), + revision: mm.revision(), + } } type matcher interface { name() string + revision() uint8 } // matchMakers maps the name of supported matchers to the matchMaker that // marshals and unmarshals it. It is immutable after package initialization. -var matchMakers = map[string]matchMaker{} +var matchMakers = map[matchKey]matchMaker{} // registermatchMaker should be called by match extensions to register them // with the netfilter package. func registerMatchMaker(mm matchMaker) { - if _, ok := matchMakers[mm.name()]; ok { - panic(fmt.Sprintf("Multiple matches registered with name %q.", mm.name())) + if _, ok := matchMakers[key(mm)]; ok { + panic(fmt.Sprintf("Multiple matches registered with key %+v.", key(mm))) } - matchMakers[mm.name()] = mm + matchMakers[key(mm)] = mm } func marshalMatcher(mr stack.Matcher) []byte { matcher := mr.(matcher) - matchMaker, ok := matchMakers[matcher.name()] + key := matchKey{ + name: matcher.name(), + revision: matcher.revision(), + } + matchMaker, ok := matchMakers[key] if !ok { panic(fmt.Sprintf("Unknown matcher of type %T.", matcher)) } @@ -85,12 +105,16 @@ func marshalEntryMatch(name string, data []byte) []byte { return buf } -func unmarshalMatcher(task *kernel.Task, match linux.XTEntryMatch, filter stack.IPHeaderFilter, buf []byte) (stack.Matcher, error) { - matchMaker, ok := matchMakers[match.Name.String()] +func unmarshalMatcher(mapper IDMapper, match linux.XTEntryMatch, filter stack.IPHeaderFilter, buf []byte) (stack.Matcher, error) { + key := matchKey{ + name: match.Name.String(), + revision: match.Revision, + } + matchMaker, ok := matchMakers[key] if !ok { - return nil, fmt.Errorf("unsupported matcher with name %q", match.Name.String()) + return nil, fmt.Errorf("unsupported matcher with name %q and revision %d", match.Name.String(), match.Revision) } - return matchMaker.unmarshal(task, buf, filter) + return matchMaker.unmarshal(mapper, buf, filter) } // targetMaker knows how to (un)marshal a target. Once registered, diff --git a/pkg/sentry/socket/netfilter/ipv4.go b/pkg/sentry/socket/netfilter/ipv4.go index f3dbf5612c..8539568379 100644 --- a/pkg/sentry/socket/netfilter/ipv4.go +++ b/pkg/sentry/socket/netfilter/ipv4.go @@ -18,7 +18,6 @@ import ( "fmt" "gvisor.dev/gvisor/pkg/abi/linux" - "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/syserr" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" @@ -126,7 +125,7 @@ func getEntries4(table stack.Table, tablename linux.TableName) (linux.KernelIPTG return entries, info } -func modifyEntries4(task *kernel.Task, stk *stack.Stack, optVal []byte, replace *linux.IPTReplace, table *stack.Table) (map[uint32]int, *syserr.Error) { +func modifyEntries4(mapper IDMapper, stk *stack.Stack, optVal []byte, replace *linux.IPTReplace, table *stack.Table) (map[uint32]int, *syserr.Error) { nflog("set entries: setting entries in table %q", replace.Name.String()) // Convert input into a list of rules and their offsets. @@ -162,7 +161,7 @@ func modifyEntries4(task *kernel.Task, stk *stack.Stack, optVal []byte, replace nflog("entry doesn't have enough room for its matchers (only %d bytes remain)", len(optVal)) return nil, syserr.ErrInvalidArgument } - matchers, err := parseMatchers(task, filter, optVal[:matchersSize]) + matchers, err := parseMatchers(mapper, filter, optVal[:matchersSize]) if err != nil { nflog("failed to parse matchers: %v", err) return nil, syserr.ErrInvalidArgument diff --git a/pkg/sentry/socket/netfilter/ipv6.go b/pkg/sentry/socket/netfilter/ipv6.go index e1c02c100c..51e1ca58bd 100644 --- a/pkg/sentry/socket/netfilter/ipv6.go +++ b/pkg/sentry/socket/netfilter/ipv6.go @@ -18,7 +18,6 @@ import ( "fmt" "gvisor.dev/gvisor/pkg/abi/linux" - "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/syserr" "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/header" @@ -129,7 +128,7 @@ func getEntries6(table stack.Table, tablename linux.TableName) (linux.KernelIP6T return entries, info } -func modifyEntries6(task *kernel.Task, stk *stack.Stack, optVal []byte, replace *linux.IPTReplace, table *stack.Table) (map[uint32]int, *syserr.Error) { +func modifyEntries6(mapper IDMapper, stk *stack.Stack, optVal []byte, replace *linux.IPTReplace, table *stack.Table) (map[uint32]int, *syserr.Error) { nflog("set entries: setting entries in table %q", replace.Name.String()) // Convert input into a list of rules and their offsets. @@ -165,7 +164,7 @@ func modifyEntries6(task *kernel.Task, stk *stack.Stack, optVal []byte, replace nflog("entry doesn't have enough room for its matchers (only %d bytes remain)", len(optVal)) return nil, syserr.ErrInvalidArgument } - matchers, err := parseMatchers(task, filter, optVal[:matchersSize]) + matchers, err := parseMatchers(mapper, filter, optVal[:matchersSize]) if err != nil { nflog("failed to parse matchers: %v", err) return nil, syserr.ErrInvalidArgument diff --git a/pkg/sentry/socket/netfilter/istio_blob b/pkg/sentry/socket/netfilter/istio_blob new file mode 100755 index 0000000000000000000000000000000000000000..31142ffa08a929f49b57022db00c9f9a0dfd925c GIT binary patch literal 5688 zcmds5u};G<5WONmMJz~&iG`7|WARi$J7j54Xy$?t8)_p|iILx+OVzPMEAbf}8Tka} zPDn@;JI$$XZQ{iBiKvz$+ZX5j-rePVN$0KyY3-EXJmc5L$zoNd1Tg1q%KNV!fLAU? z*)5+78D-l~lt+AL4nb+>ieyz#+g+Wzp4sC1;Wl-RMb;;9>0D#77Zonqk7XHXGB)9= z9BLkNC=&Lv!9`^+q$Y43;Y8|9_M*r2CZSmlYtRS+KUfOZM&3=!^V?qY(hr;UwR;p( zjJqLBwfUn0z56J2R!;eYN0}+9`i;7Bhb033h6*Z%_Y|nY`_LYP-C^i-#VQCm3NWr zX8!iW)^$kj>KH2eTby^gdM3+xXLC-x0K{91Zw0iO+&^~ZnL7UCF%a>f&Z6CZjV&(f oxZJF6Nv{p 0 { @@ -318,7 +325,7 @@ func parseMatchers(task *kernel.Task, filter stack.IPHeaderFilter, optVal []byte } // Parse the specific matcher. - matcher, err := unmarshalMatcher(task, match, filter, optVal[linux.SizeOfXTEntryMatch:match.MatchSize]) + matcher, err := unmarshalMatcher(mapper, match, filter, optVal[linux.SizeOfXTEntryMatch:match.MatchSize]) if err != nil { return nil, fmt.Errorf("failed to create matcher: %v", err) } diff --git a/pkg/sentry/socket/netfilter/netfilter_test.go b/pkg/sentry/socket/netfilter/netfilter_test.go new file mode 100644 index 0000000000..bd36d5f523 --- /dev/null +++ b/pkg/sentry/socket/netfilter/netfilter_test.go @@ -0,0 +1,56 @@ +// Copyright 2023 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package netfilter + +import ( + _ "embed" + "testing" + + "gvisor.dev/gvisor/pkg/sentry/kernel/auth" + "gvisor.dev/gvisor/pkg/tcpip/stack" +) + +// istioBlob is a golden iptables ruleset generated by Istio. It is already in +// the format ready to by passed to IPT_SO_SET_REPLACE. +// +// Updating this requires running Istio, calling IPT_SO_GET_INFO and +// IPT_SO_GET_ENTRIES, then stitching the structs up. So be careful when +// updating! +// +//go:embed istio_blob +var istioBlob []byte + +// FakeIDMapper implements IDMapper. +type FakeIDMapper struct{} + +// MapToKUID implements IDMapper. +func (*FakeIDMapper) MapToKUID(auth.UID) auth.KUID { + return 0 +} + +// MapToKGID implements IDMapper. +func (*FakeIDMapper) MapToKGID(auth.GID) auth.KGID { + return 0 +} + +// TestIstioBlob tests that we support the iptables ruleset generated by Istio, +// i.e. that we can parse the rules and set them in netstack. +func TestIstioBlob(t *testing.T) { + mapper := FakeIDMapper{} + stack := stack.New(stack.Options{}) + if err := SetEntries(&mapper, stack, istioBlob, false); err != nil { + t.Fatalf("failed to set Istio rules, try setting enableLogging and running again: %v", err) + } +} diff --git a/pkg/sentry/socket/netfilter/owner_matcher.go b/pkg/sentry/socket/netfilter/owner_matcher.go index 3a3df08384..92bc4811b9 100644 --- a/pkg/sentry/socket/netfilter/owner_matcher.go +++ b/pkg/sentry/socket/netfilter/owner_matcher.go @@ -19,7 +19,6 @@ import ( "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/marshal" - "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/sentry/kernel/auth" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -38,6 +37,10 @@ func (ownerMarshaler) name() string { return matcherNameOwner } +func (ownerMarshaler) revision() uint8 { + return 0 +} + // marshal implements matchMaker.marshal. func (ownerMarshaler) marshal(mr matcher) []byte { matcher := mr.(*OwnerMatcher) @@ -65,7 +68,7 @@ func (ownerMarshaler) marshal(mr matcher) []byte { } // unmarshal implements matchMaker.unmarshal. -func (ownerMarshaler) unmarshal(task *kernel.Task, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) { +func (ownerMarshaler) unmarshal(mapper IDMapper, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) { if len(buf) < linux.SizeOfIPTOwnerInfo { return nil, fmt.Errorf("buf has insufficient size for owner match: %d", len(buf)) } @@ -77,9 +80,8 @@ func (ownerMarshaler) unmarshal(task *kernel.Task, buf []byte, filter stack.IPHe nflog("parsed IPTOwnerInfo: %+v", matchData) var owner OwnerMatcher - creds := task.Credentials() - owner.uid = creds.UserNamespace.MapToKUID(auth.UID(matchData.UID)) - owner.gid = creds.UserNamespace.MapToKGID(auth.GID(matchData.GID)) + owner.uid = mapper.MapToKUID(auth.UID(matchData.UID)) + owner.gid = mapper.MapToKGID(auth.GID(matchData.GID)) // Check flags. if matchData.Match&linux.XT_OWNER_UID != 0 { @@ -113,6 +115,10 @@ func (*OwnerMatcher) name() string { return matcherNameOwner } +func (*OwnerMatcher) revision() uint8 { + return 0 +} + // Match implements Matcher.Match. func (om *OwnerMatcher) Match(hook stack.Hook, pkt stack.PacketBufferPtr, _, _ string) (bool, bool) { // Support only for OUTPUT chain. diff --git a/pkg/sentry/socket/netfilter/owner_matcher_v1.go b/pkg/sentry/socket/netfilter/owner_matcher_v1.go new file mode 100644 index 0000000000..8c740745e1 --- /dev/null +++ b/pkg/sentry/socket/netfilter/owner_matcher_v1.go @@ -0,0 +1,152 @@ +// Copyright 2023 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package netfilter + +import ( + "fmt" + + "gvisor.dev/gvisor/pkg/abi/linux" + "gvisor.dev/gvisor/pkg/marshal" + "gvisor.dev/gvisor/pkg/sentry/kernel/auth" + "gvisor.dev/gvisor/pkg/tcpip/stack" +) + +func init() { + registerMatchMaker(ownerMarshalerV1{}) +} + +// ownerMarshalerV1 implements matchMaker for owner matching. +type ownerMarshalerV1 struct{} + +// name implements matchMaker.name. +func (ownerMarshalerV1) name() string { + return matcherNameOwner +} + +func (ownerMarshalerV1) revision() uint8 { + return 1 +} + +// marshal implements matchMaker.marshal. +func (ownerMarshalerV1) marshal(mr matcher) []byte { + matcher := mr.(*OwnerMatcherV1) + ownerInfo := linux.XTOwnerMatchInfo{ + UIDMin: uint32(matcher.uid), + UIDMax: uint32(matcher.uid), + GIDMin: uint32(matcher.gid), + GIDMax: uint32(matcher.gid), + } + + // Support for UID and GID match. + if matcher.matchUID { + ownerInfo.Match |= linux.XT_OWNER_UID + } + if matcher.matchGID { + ownerInfo.Match |= linux.XT_OWNER_GID + } + if matcher.invertUID { + ownerInfo.Invert |= linux.XT_OWNER_UID + } + if matcher.invertGID { + ownerInfo.Invert |= linux.XT_OWNER_GID + } + buf := marshal.Marshal(&ownerInfo) + return marshalEntryMatch(matcherNameOwner, buf) +} + +// unmarshal implements matchMaker.unmarshal. +func (ownerMarshalerV1) unmarshal(mapper IDMapper, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) { + if len(buf) < linux.SizeOfXTOwnerMatchInfo { + return nil, fmt.Errorf("buf has insufficient size for owner match: %d", len(buf)) + } + + // For alignment reasons, the match's total size may + // exceed what's strictly necessary to hold matchData. + var matchData linux.XTOwnerMatchInfo + matchData.UnmarshalUnsafe(buf) + nflog("parsed XTOwnerMatchInfo: %+v", matchData) + + if matchData.UIDMin != matchData.UIDMax { + nflog("owner v1 doesn't support differing UID min/max") + } + if matchData.GIDMin != matchData.GIDMax { + nflog("owner v1 doesn't support differing GID min/max") + } + owner := OwnerMatcherV1{ + uid: mapper.MapToKUID(auth.UID(matchData.UIDMin)), + gid: mapper.MapToKGID(auth.GID(matchData.GIDMin)), + matchUID: matchData.Match&linux.XT_OWNER_UID != 0, + matchGID: matchData.Match&linux.XT_OWNER_GID != 0, + invertUID: matchData.Invert&linux.XT_OWNER_UID != 0, + invertGID: matchData.Invert&linux.XT_OWNER_GID != 0, + } + return &owner, nil +} + +// OwnerMatcherV1 matches against a UID and/or GID. +type OwnerMatcherV1 struct { + uid auth.KUID + gid auth.KGID + matchUID bool + matchGID bool + invertUID bool + invertGID bool +} + +// name implements matcher.name. +func (*OwnerMatcherV1) name() string { + return matcherNameOwner +} + +func (*OwnerMatcherV1) revision() uint8 { + return 1 +} + +// Match implements Matcher.Match. +func (om *OwnerMatcherV1) Match(hook stack.Hook, pkt stack.PacketBufferPtr, _, _ string) (bool, bool) { + // Support only for OUTPUT chain. + if hook != stack.Output { + return false, true + } + + // If the packet owner is not set, drop the packet. + if pkt.Owner == nil { + return false, true + } + + var matches bool + // Check for UID match. + if om.matchUID { + if auth.KUID(pkt.Owner.KUID()) == om.uid { + matches = true + } + if matches == om.invertUID { + return false, false + } + } + + // Check for GID match. + if om.matchGID { + matches = false + if auth.KGID(pkt.Owner.KGID()) == om.gid { + matches = true + } + if matches == om.invertGID { + return false, false + } + } + + return true, false +} diff --git a/pkg/sentry/socket/netfilter/tcp_matcher.go b/pkg/sentry/socket/netfilter/tcp_matcher.go index 7d5b95cc76..264a5b0aea 100644 --- a/pkg/sentry/socket/netfilter/tcp_matcher.go +++ b/pkg/sentry/socket/netfilter/tcp_matcher.go @@ -19,7 +19,6 @@ import ( "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/marshal" - "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -38,6 +37,10 @@ func (tcpMarshaler) name() string { return matcherNameTCP } +func (tcpMarshaler) revision() uint8 { + return 0 +} + // marshal implements matchMaker.marshal. func (tcpMarshaler) marshal(mr matcher) []byte { matcher := mr.(*TCPMatcher) @@ -51,7 +54,7 @@ func (tcpMarshaler) marshal(mr matcher) []byte { } // unmarshal implements matchMaker.unmarshal. -func (tcpMarshaler) unmarshal(_ *kernel.Task, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) { +func (tcpMarshaler) unmarshal(_ IDMapper, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) { if len(buf) < linux.SizeOfXTTCP { return nil, fmt.Errorf("buf has insufficient size for TCP match: %d", len(buf)) } @@ -94,6 +97,10 @@ func (*TCPMatcher) name() string { return matcherNameTCP } +func (*TCPMatcher) revision() uint8 { + return 0 +} + // Match implements Matcher.Match. func (tm *TCPMatcher) Match(hook stack.Hook, pkt stack.PacketBufferPtr, _, _ string) (bool, bool) { switch pkt.NetworkProtocolNumber { diff --git a/pkg/sentry/socket/netfilter/udp_matcher.go b/pkg/sentry/socket/netfilter/udp_matcher.go index 7d7bc3c950..73aa15eefc 100644 --- a/pkg/sentry/socket/netfilter/udp_matcher.go +++ b/pkg/sentry/socket/netfilter/udp_matcher.go @@ -19,7 +19,6 @@ import ( "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/marshal" - "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/tcpip/header" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -38,6 +37,10 @@ func (udpMarshaler) name() string { return matcherNameUDP } +func (udpMarshaler) revision() uint8 { + return 0 +} + // marshal implements matchMaker.marshal. func (udpMarshaler) marshal(mr matcher) []byte { matcher := mr.(*UDPMatcher) @@ -51,7 +54,7 @@ func (udpMarshaler) marshal(mr matcher) []byte { } // unmarshal implements matchMaker.unmarshal. -func (udpMarshaler) unmarshal(_ *kernel.Task, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) { +func (udpMarshaler) unmarshal(_ IDMapper, buf []byte, filter stack.IPHeaderFilter) (stack.Matcher, error) { if len(buf) < linux.SizeOfXTUDP { return nil, fmt.Errorf("buf has insufficient size for UDP match: %d", len(buf)) } @@ -91,6 +94,10 @@ func (*UDPMatcher) name() string { return matcherNameUDP } +func (*UDPMatcher) revision() uint8 { + return 0 +} + // Match implements Matcher.Match. func (um *UDPMatcher) Match(hook stack.Hook, pkt stack.PacketBufferPtr, _, _ string) (bool, bool) { switch pkt.NetworkProtocolNumber { diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index e177f84870..e1cfbf61c0 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -2311,7 +2311,7 @@ func setSockOptIPv6(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int return syserr.ErrNoDevice } // Stack must be a netstack stack. - return netfilter.SetEntries(t, stk.(*Stack).Stack, optVal, true) + return netfilter.SetEntries(t.Credentials().UserNamespace, stk.(*Stack).Stack, optVal, true) case linux.IP6T_SO_SET_ADD_COUNTERS: log.Infof("IP6T_SO_SET_ADD_COUNTERS is not supported") @@ -2558,7 +2558,7 @@ func setSockOptIP(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int, return syserr.ErrNoDevice } // Stack must be a netstack stack. - return netfilter.SetEntries(t, stk.(*Stack).Stack, optVal, false) + return netfilter.SetEntries(t.Credentials().UserNamespace, stk.(*Stack).Stack, optVal, false) case linux.IPT_SO_SET_ADD_COUNTERS: log.Infof("IPT_SO_SET_ADD_COUNTERS is not supported")