diff options
Diffstat (limited to 'runsc')
-rw-r--r-- | runsc/boot/network.go | 42 | ||||
-rw-r--r-- | runsc/fsgofer/fsgofer.go | 10 | ||||
-rw-r--r-- | runsc/fsgofer/fsgofer_test.go | 50 | ||||
-rw-r--r-- | runsc/main.go | 8 | ||||
-rw-r--r-- | runsc/sandbox/network.go | 31 | ||||
-rw-r--r-- | runsc/sandbox/sandbox.go | 2 | ||||
-rw-r--r-- | runsc/test/testutil/testutil.go | 16 |
7 files changed, 124 insertions, 35 deletions
diff --git a/runsc/boot/network.go b/runsc/boot/network.go index d3d98243d..ea0d9f790 100644 --- a/runsc/boot/network.go +++ b/runsc/boot/network.go @@ -38,8 +38,7 @@ type Network struct { // Route represents a route in the network stack. type Route struct { - Destination net.IP - Mask net.IPMask + Destination net.IPNet Gateway net.IP } @@ -85,16 +84,19 @@ type CreateLinksAndRoutesArgs struct { // Empty returns true if route hasn't been set. func (r *Route) Empty() bool { - return r.Destination == nil && r.Mask == nil && r.Gateway == nil + return r.Destination.IP == nil && r.Destination.Mask == nil && r.Gateway == nil } -func (r *Route) toTcpipRoute(id tcpip.NICID) tcpip.Route { +func (r *Route) toTcpipRoute(id tcpip.NICID) (tcpip.Route, error) { + subnet, err := tcpip.NewSubnet(ipToAddress(r.Destination.IP), ipMaskToAddressMask(r.Destination.Mask)) + if err != nil { + return tcpip.Route{}, err + } return tcpip.Route{ - Destination: ipToAddress(r.Destination), + Destination: subnet, Gateway: ipToAddress(r.Gateway), - Mask: ipToAddressMask(net.IP(r.Mask)), NIC: id, - } + }, nil } // CreateLinksAndRoutes creates links and routes in a network stack. It should @@ -128,7 +130,11 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct // Collect the routes from this link. for _, r := range link.Routes { - routes = append(routes, r.toTcpipRoute(nicID)) + route, err := r.toTcpipRoute(nicID) + if err != nil { + return err + } + routes = append(routes, route) } } @@ -170,7 +176,11 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct // Collect the routes from this link. for _, r := range link.Routes { - routes = append(routes, r.toTcpipRoute(nicID)) + route, err := r.toTcpipRoute(nicID) + if err != nil { + return err + } + routes = append(routes, route) } } @@ -179,7 +189,11 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct if !ok { return fmt.Errorf("invalid interface name %q for default route", args.DefaultGateway.Name) } - routes = append(routes, args.DefaultGateway.Route.toTcpipRoute(nicID)) + route, err := args.DefaultGateway.Route.toTcpipRoute(nicID) + if err != nil { + return err + } + routes = append(routes, route) } log.Infof("Setting routes %+v", routes) @@ -230,8 +244,8 @@ func ipToAddress(ip net.IP) tcpip.Address { return addr } -// ipToAddressMask converts IP to tcpip.AddressMask, ignoring the protocol. -func ipToAddressMask(ip net.IP) tcpip.AddressMask { - _, addr := ipToAddressAndProto(ip) - return tcpip.AddressMask(addr) +// ipMaskToAddressMask converts IPMask to tcpip.AddressMask, ignoring the +// protocol. +func ipMaskToAddressMask(ipMask net.IPMask) tcpip.AddressMask { + return tcpip.AddressMask(ipToAddress(net.IP(ipMask))) } diff --git a/runsc/fsgofer/fsgofer.go b/runsc/fsgofer/fsgofer.go index fe450c64f..7c4d2b94e 100644 --- a/runsc/fsgofer/fsgofer.go +++ b/runsc/fsgofer/fsgofer.go @@ -125,7 +125,7 @@ func (a *attachPoint) Attach() (p9.File, error) { return nil, fmt.Errorf("stat file %q, err: %v", a.prefix, err) } mode := syscall.O_RDWR - if a.conf.ROMount || stat.Mode&syscall.S_IFDIR != 0 { + if a.conf.ROMount || (stat.Mode&syscall.S_IFMT) == syscall.S_IFDIR { mode = syscall.O_RDONLY } @@ -141,9 +141,13 @@ func (a *attachPoint) Attach() (p9.File, error) { f.Close() return nil, fmt.Errorf("attach point already attached, prefix: %s", a.prefix) } - a.attached = true - return newLocalFile(a, f, a.prefix, stat) + rv, err := newLocalFile(a, f, a.prefix, stat) + if err != nil { + return nil, err + } + a.attached = true + return rv, nil } // makeQID returns a unique QID for the given stat buffer. diff --git a/runsc/fsgofer/fsgofer_test.go b/runsc/fsgofer/fsgofer_test.go index 0a162bb8a..cbbe71019 100644 --- a/runsc/fsgofer/fsgofer_test.go +++ b/runsc/fsgofer/fsgofer_test.go @@ -17,8 +17,10 @@ package fsgofer import ( "fmt" "io/ioutil" + "net" "os" "path" + "path/filepath" "syscall" "testing" @@ -621,6 +623,54 @@ func TestAttachFile(t *testing.T) { } } +func TestAttachInvalidType(t *testing.T) { + dir, err := ioutil.TempDir("", "attach-") + if err != nil { + t.Fatalf("ioutil.TempDir() failed, err: %v", err) + } + defer os.RemoveAll(dir) + + fifo := filepath.Join(dir, "fifo") + if err := syscall.Mkfifo(fifo, 0755); err != nil { + t.Fatalf("Mkfifo(%q): %v", fifo, err) + } + + dirFile, err := os.Open(dir) + if err != nil { + t.Fatalf("Open(%s): %v", dir, err) + } + defer dirFile.Close() + + // Bind a socket via /proc to be sure that a length of a socket path + // is less than UNIX_PATH_MAX. + socket := filepath.Join(fmt.Sprintf("/proc/self/fd/%d", dirFile.Fd()), "socket") + l, err := net.Listen("unix", socket) + if err != nil { + t.Fatalf("net.Listen(unix, %q): %v", socket, err) + } + defer l.Close() + + for _, tc := range []struct { + name string + path string + }{ + {name: "fifo", path: fifo}, + {name: "socket", path: socket}, + } { + t.Run(tc.name, func(t *testing.T) { + conf := Config{ROMount: false} + a, err := NewAttachPoint(tc.path, conf) + if err != nil { + t.Fatalf("NewAttachPoint failed: %v", err) + } + f, err := a.Attach() + if f != nil || err == nil { + t.Fatalf("Attach should have failed, got (%v, nil)", f) + } + }) + } +} + func TestDoubleAttachError(t *testing.T) { conf := Config{ROMount: false} root, err := ioutil.TempDir("", "root-") diff --git a/runsc/main.go b/runsc/main.go index 5823819f4..c61583441 100644 --- a/runsc/main.go +++ b/runsc/main.go @@ -22,6 +22,7 @@ import ( "io" "io/ioutil" "os" + "os/signal" "path/filepath" "strings" "syscall" @@ -257,6 +258,13 @@ func main() { log.Infof("\t\tStrace: %t, max size: %d, syscalls: %s", conf.Strace, conf.StraceLogSize, conf.StraceSyscalls) log.Infof("***************************") + if *testOnlyAllowRunAsCurrentUserWithoutChroot { + // SIGTERM is sent to all processes if a test exceeds its + // timeout and this case is handled by syscall_test_runner. + log.Warningf("Block the TERM signal. This is only safe in tests!") + signal.Ignore(syscall.SIGTERM) + } + // Call the subcommand and pass in the configuration. var ws syscall.WaitStatus subcmdCode := subcommands.Execute(context.Background(), conf, &ws) diff --git a/runsc/sandbox/network.go b/runsc/sandbox/network.go index 333ffb65c..5634f0707 100644 --- a/runsc/sandbox/network.go +++ b/runsc/sandbox/network.go @@ -81,12 +81,17 @@ func createDefaultLoopbackInterface(conn *urpc.Client) error { }, Routes: []boot.Route{ { - Destination: net.IP("\x7f\x00\x00\x00"), - Mask: net.IPMask("\xff\x00\x00\x00"), + Destination: net.IPNet{ + + IP: net.IPv4(0x7f, 0, 0, 0), + Mask: net.IPv4Mask(0xff, 0, 0, 0), + }, }, { - Destination: net.IPv6loopback, - Mask: net.IPMask(strings.Repeat("\xff", 16)), + Destination: net.IPNet{ + IP: net.IPv6loopback, + Mask: net.IPMask(strings.Repeat("\xff", net.IPv6len)), + }, }, }, } @@ -326,12 +331,13 @@ func loopbackLinks(iface net.Interface, addrs []net.Addr) ([]boot.LoopbackLink, if !ok { return nil, fmt.Errorf("address is not IPNet: %+v", addr) } + dst := *ipNet + dst.IP = dst.IP.Mask(dst.Mask) links = append(links, boot.LoopbackLink{ Name: iface.Name, Addresses: []net.IP{ipNet.IP}, Routes: []boot.Route{{ - Destination: ipNet.IP.Mask(ipNet.Mask), - Mask: ipNet.Mask, + Destination: dst, }}, }) } @@ -367,9 +373,11 @@ func routesForIface(iface net.Interface) ([]boot.Route, *boot.Route, error) { } // Create a catch all route to the gateway. def = &boot.Route{ - Destination: net.IPv4zero, - Mask: net.IPMask(net.IPv4zero), - Gateway: r.Gw, + Destination: net.IPNet{ + IP: net.IPv4zero, + Mask: net.IPMask(net.IPv4zero), + }, + Gateway: r.Gw, } continue } @@ -377,9 +385,10 @@ func routesForIface(iface net.Interface) ([]boot.Route, *boot.Route, error) { log.Warningf("IPv6 is not supported, skipping route: %v", r) continue } + dst := *r.Dst + dst.IP = dst.IP.Mask(dst.Mask) routes = append(routes, boot.Route{ - Destination: r.Dst.IP.Mask(r.Dst.Mask), - Mask: r.Dst.Mask, + Destination: dst, Gateway: r.Gw, }) } diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go index 851b1304b..df3c0c5ef 100644 --- a/runsc/sandbox/sandbox.go +++ b/runsc/sandbox/sandbox.go @@ -361,6 +361,8 @@ func (s *Sandbox) createSandboxProcess(conf *boot.Config, args *Args, startSyncF nextFD++ } + cmd.Args = append(cmd.Args, "--panic-signal="+strconv.Itoa(int(syscall.SIGTERM))) + // Add the "boot" command to the args. // // All flags after this must be for the boot command diff --git a/runsc/test/testutil/testutil.go b/runsc/test/testutil/testutil.go index e288c7758..4a3dfa0e3 100644 --- a/runsc/test/testutil/testutil.go +++ b/runsc/test/testutil/testutil.go @@ -127,13 +127,15 @@ func FindFile(path string) (string, error) { // 'RootDir' must be set by caller if required. func TestConfig() *boot.Config { return &boot.Config{ - Debug: true, - LogFormat: "text", - LogPackets: true, - Network: boot.NetworkNone, - Strace: true, - Platform: "ptrace", - FileAccess: boot.FileAccessExclusive, + Debug: true, + LogFormat: "text", + DebugLogFormat: "text", + AlsoLogToStderr: true, + LogPackets: true, + Network: boot.NetworkNone, + Strace: true, + Platform: "ptrace", + FileAccess: boot.FileAccessExclusive, TestOnlyAllowRunAsCurrentUserWithoutChroot: true, NumNetworkChannels: 1, } |