summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/socket
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-01-21 12:08:52 -0800
committergVisor bot <gvisor-bot@google.com>2020-01-21 12:08:52 -0800
commit5f82f092e7c5df8be8f9f8bacfbc135792ff2f5e (patch)
tree7fba07b20cb84ab828c62ec690a1be6abb2c17cd /pkg/sentry/socket
parent7e155a133bac499d7b1e4490ae6f0c08b28a4006 (diff)
parent95e9de31d20ee1c7262fe5870e10485a369e6497 (diff)
Merge pull request #1558 from kevinGC:iptables-write-input-drop
PiperOrigin-RevId: 290793754
Diffstat (limited to 'pkg/sentry/socket')
-rw-r--r--pkg/sentry/socket/netfilter/BUILD1
-rw-r--r--pkg/sentry/socket/netfilter/netfilter.go40
-rw-r--r--pkg/sentry/socket/netstack/netstack.go12
3 files changed, 35 insertions, 18 deletions
diff --git a/pkg/sentry/socket/netfilter/BUILD b/pkg/sentry/socket/netfilter/BUILD
index b70047d81..2e581e9d2 100644
--- a/pkg/sentry/socket/netfilter/BUILD
+++ b/pkg/sentry/socket/netfilter/BUILD
@@ -18,7 +18,6 @@ go_library(
"//pkg/sentry/kernel",
"//pkg/sentry/usermem",
"//pkg/syserr",
- "//pkg/tcpip",
"//pkg/tcpip/iptables",
"//pkg/tcpip/stack",
],
diff --git a/pkg/sentry/socket/netfilter/netfilter.go b/pkg/sentry/socket/netfilter/netfilter.go
index a9cfc1749..507a77483 100644
--- a/pkg/sentry/socket/netfilter/netfilter.go
+++ b/pkg/sentry/socket/netfilter/netfilter.go
@@ -25,7 +25,6 @@ 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"
)
@@ -45,7 +44,7 @@ type metadata struct {
}
// GetInfo returns information about iptables.
-func GetInfo(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr) (linux.IPTGetinfo, *syserr.Error) {
+func GetInfo(t *kernel.Task, stack *stack.Stack, outPtr usermem.Addr) (linux.IPTGetinfo, *syserr.Error) {
// Read in the struct and table name.
var info linux.IPTGetinfo
if _, err := t.CopyIn(outPtr, &info); err != nil {
@@ -53,7 +52,7 @@ func GetInfo(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr) (linux.IPTG
}
// Find the appropriate table.
- table, err := findTable(ep, info.Name)
+ table, err := findTable(stack, info.Name)
if err != nil {
return linux.IPTGetinfo{}, err
}
@@ -76,7 +75,7 @@ func GetInfo(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr) (linux.IPTG
}
// GetEntries returns netstack's iptables rules encoded for the iptables tool.
-func GetEntries(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr, outLen int) (linux.KernelIPTGetEntries, *syserr.Error) {
+func GetEntries(t *kernel.Task, stack *stack.Stack, outPtr usermem.Addr, outLen int) (linux.KernelIPTGetEntries, *syserr.Error) {
// Read in the struct and table name.
var userEntries linux.IPTGetEntries
if _, err := t.CopyIn(outPtr, &userEntries); err != nil {
@@ -84,7 +83,7 @@ func GetEntries(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr, outLen i
}
// Find the appropriate table.
- table, err := findTable(ep, userEntries.Name)
+ table, err := findTable(stack, userEntries.Name)
if err != nil {
return linux.KernelIPTGetEntries{}, err
}
@@ -103,11 +102,8 @@ func GetEntries(t *kernel.Task, ep tcpip.Endpoint, outPtr usermem.Addr, outLen i
return entries, nil
}
-func findTable(ep tcpip.Endpoint, tablename linux.TableName) (iptables.Table, *syserr.Error) {
- ipt, err := ep.IPTables()
- if err != nil {
- return iptables.Table{}, syserr.FromError(err)
- }
+func findTable(stack *stack.Stack, tablename linux.TableName) (iptables.Table, *syserr.Error) {
+ ipt := stack.IPTables()
table, ok := ipt.Tables[tablename.String()]
if !ok {
return iptables.Table{}, syserr.ErrInvalidArgument
@@ -348,7 +344,7 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error {
// Go through the list of supported hooks for this table and, for each
// one, set the rule it corresponds to.
for hook, _ := range replace.HookEntry {
- if table.ValidHooks()&uint32(hook) != 0 {
+ if table.ValidHooks()&(1<<hook) != 0 {
hk := hookFromLinux(hook)
for ruleIdx, offset := range offsets {
if offset == replace.HookEntry[hook] {
@@ -369,6 +365,23 @@ func SetEntries(stack *stack.Stack, optVal []byte) *syserr.Error {
}
}
+ // TODO(gvisor.dev/issue/170): Support other chains.
+ // Since we only support modifying the INPUT chain right now, make sure
+ // all other chains point to ACCEPT rules.
+ for hook, ruleIdx := range table.BuiltinChains {
+ if hook != iptables.Input {
+ if _, ok := table.Rules[ruleIdx].Target.(iptables.UnconditionalAcceptTarget); !ok {
+ log.Warningf("Hook %d is unsupported.", hook)
+ return syserr.ErrInvalidArgument
+ }
+ }
+ }
+
+ // TODO(gvisor.dev/issue/170): Check the following conditions:
+ // - There are no loops.
+ // - There are no chains without an unconditional final rule.
+ // - There are no chains without an unconditional underflow rule.
+
ipt := stack.IPTables()
table.SetMetadata(metadata{
HookEntry: replace.HookEntry,
@@ -411,10 +424,7 @@ func parseTarget(optVal []byte) (iptables.Target, uint32, *syserr.Error) {
case iptables.Accept:
return iptables.UnconditionalAcceptTarget{}, linux.SizeOfXTStandardTarget, nil
case iptables.Drop:
- // TODO(gvisor.dev/issue/170): Return an
- // iptables.UnconditionalDropTarget to support DROP.
- log.Infof("netfilter DROP is not supported yet.")
- return nil, 0, syserr.ErrInvalidArgument
+ return iptables.UnconditionalDropTarget{}, linux.SizeOfXTStandardTarget, nil
default:
panic(fmt.Sprintf("Unknown verdict: %v", verdict))
}
diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go
index fec575357..2662fbc0f 100644
--- a/pkg/sentry/socket/netstack/netstack.go
+++ b/pkg/sentry/socket/netstack/netstack.go
@@ -868,7 +868,11 @@ func (s *SocketOperations) GetSockOpt(t *kernel.Task, level, name int, outPtr us
return nil, syserr.ErrInvalidArgument
}
- info, err := netfilter.GetInfo(t, s.Endpoint, outPtr)
+ stack := inet.StackFromContext(t)
+ if stack == nil {
+ return nil, syserr.ErrNoDevice
+ }
+ info, err := netfilter.GetInfo(t, stack.(*Stack).Stack, outPtr)
if err != nil {
return nil, err
}
@@ -879,7 +883,11 @@ func (s *SocketOperations) GetSockOpt(t *kernel.Task, level, name int, outPtr us
return nil, syserr.ErrInvalidArgument
}
- entries, err := netfilter.GetEntries(t, s.Endpoint, outPtr, outLen)
+ stack := inet.StackFromContext(t)
+ if stack == nil {
+ return nil, syserr.ErrNoDevice
+ }
+ entries, err := netfilter.GetEntries(t, stack.(*Stack).Stack, outPtr, outLen)
if err != nil {
return nil, err
}