diff options
Diffstat (limited to 'pkg/sentry')
-rw-r--r-- | pkg/sentry/socket/netfilter/netfilter.go | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/pkg/sentry/socket/netfilter/netfilter.go b/pkg/sentry/socket/netfilter/netfilter.go index 507a77483..09a3276c7 100644 --- a/pkg/sentry/socket/netfilter/netfilter.go +++ b/pkg/sentry/socket/netfilter/netfilter.go @@ -25,6 +25,7 @@ import ( "gvisor.dev/gvisor/pkg/sentry/kernel" "gvisor.dev/gvisor/pkg/sentry/usermem" "gvisor.dev/gvisor/pkg/syserr" + "gvisor.dev/gvisor/pkg/tcpip" "gvisor.dev/gvisor/pkg/tcpip/iptables" "gvisor.dev/gvisor/pkg/tcpip/stack" ) @@ -323,10 +324,9 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error { // TODO(gvisor.dev/issue/170): We should support IPTIP // filtering. We reject any nonzero IPTIP values for now. - emptyIPTIP := linux.IPTIP{} - if entry.IP != emptyIPTIP { - log.Warningf("netfilter: non-empty struct iptip found") - return syserr.ErrInvalidArgument + filter, err := filterFromIPTIP(entry.IP) + if err != nil { + return err } // Get the target of the rule. @@ -336,7 +336,10 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error { } optVal = optVal[consumed:] - table.Rules = append(table.Rules, iptables.Rule{Target: target}) + table.Rules = append(table.Rules, iptables.Rule{ + Filter: filter, + Target: target, + }) offsets = append(offsets, offset) offset += linux.SizeOfIPTEntry + consumed } @@ -460,6 +463,31 @@ func parseTarget(optVal []byte) (iptables.Target, uint32, *syserr.Error) { return nil, 0, syserr.ErrInvalidArgument } +func filterFromIPTIP(iptip linux.IPTIP) (iptables.IPHeaderFilter, *syserr.Error) { + if containsUnsupportedFields(iptip) { + log.Warningf("netfilter: unsupported fields in struct iptip: %+v") + return iptables.IPHeaderFilter{}, syserr.ErrInvalidArgument + } + return iptables.IPHeaderFilter{ + Protocol: tcpip.TransportProtocolNumber(iptip.Protocol), + }, nil +} + +func containsUnsupportedFields(iptip linux.IPTIP) bool { + // Currently we check that everything except protocol is zeroed. + var emptyInetAddr = linux.InetAddr{} + var emptyInterface = [linux.IFNAMSIZ]byte{} + return iptip.Dst != emptyInetAddr || + iptip.SrcMask != emptyInetAddr || + iptip.DstMask != emptyInetAddr || + iptip.InputInterface != emptyInterface || + iptip.OutputInterface != emptyInterface || + iptip.InputInterfaceMask != emptyInterface || + iptip.OutputInterfaceMask != emptyInterface || + iptip.Flags != 0 || + iptip.InverseFlags != 0 +} + func hookFromLinux(hook int) iptables.Hook { switch hook { case linux.NF_INET_PRE_ROUTING: |