From c8d682f4b6e440915f562e20f410c53e32388a3c Mon Sep 17 00:00:00 2001 From: criyle Date: Wed, 18 Sep 2019 01:42:10 -0700 Subject: [PATCH] add mount builder & fix rlimits unit --- cmd/runprog/main.go | 25 ++++++----- daemon/default.go | 22 +--------- daemon/master.go | 17 +++++--- go.mod | 2 +- go.sum | 4 +- pkg/forkexec/fork.go | 10 +---- pkg/forkexec/fork_util.go | 46 -------------------- pkg/forkexec/runner.go | 14 +++--- pkg/mount/builder.go | 90 +++++++++++++++++++++++++++++++++++++++ pkg/mount/mount.go | 65 ++++++++++++---------------- pkg/mount/mount_linux.go | 24 +++++++++++ pkg/rlimit/rlimit.go | 18 ++++---- runner/ptrace/run.go | 2 +- runner/ptrace/runner.go | 2 +- runner/unshare/default.go | 49 ++------------------- runner/unshare/run.go | 2 +- runner/unshare/runner.go | 4 +- 17 files changed, 194 insertions(+), 202 deletions(-) create mode 100644 pkg/mount/builder.go create mode 100644 pkg/mount/mount_linux.go diff --git a/cmd/runprog/main.go b/cmd/runprog/main.go index 487e51d..93e7482 100644 --- a/cmd/runprog/main.go +++ b/cmd/runprog/main.go @@ -12,6 +12,7 @@ import ( "github.com/criyle/go-sandbox/daemon" "github.com/criyle/go-sandbox/pkg/cgroup" "github.com/criyle/go-sandbox/pkg/memfd" + "github.com/criyle/go-sandbox/pkg/mount" "github.com/criyle/go-sandbox/pkg/rlimit" "github.com/criyle/go-sandbox/pkg/seccomp" "github.com/criyle/go-sandbox/pkg/seccomp/libseccomp" @@ -205,8 +206,8 @@ func start() (*types.Result, error) { rlims := rlimit.RLimits{ CPU: timeLimit, CPUHard: realTimeLimit, - FileSize: outputLimit, - Stack: stackLimit, + FileSize: outputLimit << 20, + Stack: stackLimit << 20, } actionDefault := seccomp.ActionKill @@ -255,26 +256,24 @@ func start() (*types.Result, error) { return nil, fmt.Errorf("cannot make temp root for new namespace") } defer os.RemoveAll(root) - + mounts, err := mount.NewBuilder().WithMounts(unshare.DefaultMounts).WithBind(root, "w", true).Build(true) + if err != nil { + return nil, fmt.Errorf("cannot make rootfs mounts") + } runner = &unshare.Runner{ Args: args, Env: []string{pathEnv}, ExecFile: execFile, WorkDir: "/w", Files: fds, - RLimits: rlims, + RLimits: rlims.PrepareRLimit(), Limit: types.Limit{ TimeLimit: timeLimit * 1e3, MemoryLimit: memoryLimit << 10, }, - Seccomp: filter, - Root: root, - Mounts: unshare.GetDefaultMounts(root, []unshare.AddBind{ - { - Source: workPath, - Target: "w", - }, - }), + Seccomp: filter, + Root: root, + Mounts: mounts, ShowDetails: showDetails, SyncFunc: syncFunc, HostName: "run_program", @@ -295,7 +294,7 @@ func start() (*types.Result, error) { Env: []string{pathEnv}, ExecFile: execFile, WorkDir: workPath, - RLimits: rlims, + RLimits: rlims.PrepareRLimit(), Limit: types.Limit{ TimeLimit: timeLimit * 1e3, MemoryLimit: memoryLimit << 10, diff --git a/daemon/default.go b/daemon/default.go index d8a3b7d..5f174c1 100644 --- a/daemon/default.go +++ b/daemon/default.go @@ -1,15 +1,12 @@ package daemon import ( - "os" - "github.com/criyle/go-sandbox/pkg/mount" "golang.org/x/sys/unix" ) const ( - bind = unix.MS_BIND | unix.MS_NOSUID | unix.MS_PRIVATE - roBind = bind | unix.MS_RDONLY + roBind = unix.MS_BIND | unix.MS_NOSUID | unix.MS_PRIVATE | unix.MS_RDONLY mFlag = unix.MS_NOSUID | unix.MS_NOATIME | unix.MS_NODEV ) @@ -19,7 +16,7 @@ var ( DefaultPath = "PATH=/usr/local/bin:/usr/bin:/bin" // rootfs created by bind mounting - DefaultMounts = []*mount.Mount{ + DefaultMounts = []mount.Mount{ { Source: "/usr", Target: "usr", @@ -56,18 +53,3 @@ var ( }, } ) - -func init() { - // check if bind mount source exists, e.g. /lib64 does not exists on arm - mounts := make([]*mount.Mount, 0, len(DefaultMounts)) - for _, m := range DefaultMounts { - if m.Source != "tmpfs" { - if _, err := os.Stat(m.Source); !os.IsNotExist(err) { - mounts = append(mounts, m) - } - } else { - mounts = append(mounts, m) - } - } - DefaultMounts = mounts -} diff --git a/daemon/master.go b/daemon/master.go index bc7d734..55f9f2a 100644 --- a/daemon/master.go +++ b/daemon/master.go @@ -6,6 +6,7 @@ import ( "github.com/criyle/go-sandbox/pkg/forkexec" "github.com/criyle/go-sandbox/pkg/memfd" + "github.com/criyle/go-sandbox/pkg/mount" "github.com/criyle/go-sandbox/pkg/unixsocket" "golang.org/x/sys/unix" ) @@ -43,23 +44,28 @@ func New(root string) (*Master, error) { if err != nil { return nil, fmt.Errorf("daemon: failed to create socket(%v)", err) } + defer outs.Conn.Close() + outf, err := outs.Conn.File() if err != nil { ins.Conn.Close() - outs.Conn.Close() return nil, fmt.Errorf("daemon: failed to dup file outs(%v)", err) } defer outf.Close() + if err = ins.SetPassCred(1); err != nil { ins.Conn.Close() - outs.Conn.Close() return nil, fmt.Errorf("daemon: failed to set pass_cred ins(%v)", err) } if err = outs.SetPassCred(1); err != nil { ins.Conn.Close() - outs.Conn.Close() return nil, fmt.Errorf("daemon: failed to set pass_cred outs(%v)", err) } + mounts, err := mount.NewBuilder().WithMounts(DefaultMounts).Build(true) + if err != nil { + ins.Conn.Close() + return nil, fmt.Errorf("daemon: failed to build rootfs mount %v", err) + } r := &forkexec.Runner{ Args: []string{os.Args[0], initArg}, @@ -68,7 +74,7 @@ func New(root string) (*Master, error) { Files: []uintptr{fnull.Fd(), fnull.Fd(), fnull.Fd(), uintptr(outf.Fd())}, WorkDir: "/w", UnshareFlags: forkexec.UnshareFlags, - Mounts: DefaultMounts, + Mounts: mounts, HostName: "daemon", DomainName: "daemon", PivotRoot: root, @@ -76,11 +82,8 @@ func New(root string) (*Master, error) { pid, err := r.Start() if err != nil { ins.Conn.Close() - outs.Conn.Close() return nil, fmt.Errorf("daemon: failed to execve(%v)", err) } - - outs.Conn.Close() return &Master{pid, ins}, nil } diff --git a/go.mod b/go.mod index a77c3dc..5754fc4 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.12 require ( github.com/seccomp/libseccomp-golang v0.9.1 - golang.org/x/sys v0.0.0-20190913121621-c3b328c6e5a7 + golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 ) diff --git a/go.sum b/go.sum index 06a218e..c2acd20 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -golang.org/x/sys v0.0.0-20190913121621-c3b328c6e5a7 h1:wYqz/tQaWUgGKyx+B/rssSE6wkIKdY5Ee6ryOmzarIg= -golang.org/x/sys v0.0.0-20190913121621-c3b328c6e5a7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3 h1:7TYNF4UdlohbFwpNH04CoPMp1cHUZgO1Ebq5r2hIjfo= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/pkg/forkexec/fork.go b/pkg/forkexec/fork.go index 0363fca..d4d2296 100644 --- a/pkg/forkexec/fork.go +++ b/pkg/forkexec/fork.go @@ -58,12 +58,6 @@ func (r *Runner) Start() (int, error) { return 0, err } - // prepare mount param - mountParams, dirsToMake, err := prepareMounts(r.Mounts) - if err != nil { - return 0, nil - } - // socketpair p used to notify child the uid / gid mapping have been setup // socketpair p is also used to sync with parent before final execve // p[0] is used by parent and p[1] is used by child @@ -277,9 +271,9 @@ func (r *Runner) Start() (int, error) { } // performing mounts - for i, m := range mountParams { + for _, m := range r.Mounts { // mkdirs(target) - for _, p := range dirsToMake[i] { + for _, p := range m.Prefixes { _, _, err1 = syscall.RawSyscall(syscall.SYS_MKDIRAT, uintptr(_AT_FDCWD), uintptr(unsafe.Pointer(p)), 0755) if err1 != 0 && err1 != syscall.EEXIST { goto childerror diff --git a/pkg/forkexec/fork_util.go b/pkg/forkexec/fork_util.go index 1ce8f54..462b3a1 100644 --- a/pkg/forkexec/fork_util.go +++ b/pkg/forkexec/fork_util.go @@ -2,8 +2,6 @@ package forkexec import ( "syscall" - - "github.com/criyle/go-sandbox/pkg/mount" ) // prepareExec prepares execve parameters @@ -63,47 +61,3 @@ func preparePivotRoot(r string) (*byte, *byte, error) { } return root, oldRoot, nil } - -// prepareMounts prepare mkdir and mount syscall params -func prepareMounts(ms []*mount.Mount) ([]*mount.SyscallParams, [][]*byte, error) { - params, err := mount.ToSyscalls(ms) - if err != nil { - return nil, nil, err - } - // evaluate paths that need to be created - pathsToCreate := make([][]*byte, 0, len(ms)) - for _, m := range ms { - prefix := pathPrefix(m.Target) - paths, err := arrayPtrFromStrings(prefix) - if err != nil { - return nil, nil, err - } - pathsToCreate = append(pathsToCreate, paths) - } - return params, pathsToCreate, nil -} - -// pathPrefix get all components from path -func pathPrefix(path string) []string { - ret := make([]string, 0) - for i := 1; i < len(path); i++ { - if path[i] == '/' { - ret = append(ret, path[:i]) - } - } - ret = append(ret, path) - return ret -} - -// arrayPtrFromStrings convers srings to c style strings -func arrayPtrFromStrings(strs []string) ([]*byte, error) { - bytes := make([]*byte, 0, len(strs)) - for _, s := range strs { - b, err := syscall.BytePtrFromString(s) - if err != nil { - return nil, err - } - bytes = append(bytes, b) - } - return bytes, nil -} diff --git a/pkg/forkexec/runner.go b/pkg/forkexec/runner.go index a67ab3c..9f63808 100644 --- a/pkg/forkexec/runner.go +++ b/pkg/forkexec/runner.go @@ -56,17 +56,14 @@ type Runner struct { // need CAP_SYS_ADMIN inside the namespace (e.g. unshare user namespace) // if pivot root is provided, relative target is better for chdir-mount meta // and pivot root will mount as tmpfs before any mount - Mounts []*mount.Mount - - // HostName and DomainName to be set after unshare UTS & user (CAP_SYS_ADMIN) - HostName, DomainName string + Mounts []mount.SyscallParams // pivot_root defines a readonly new root after unshare mount namespace - // it should be a directory in absolute path - // Before mounts, tt will call: + // it should be a directory in absolute path and should used with mounts + // Call path: // mount("tmpfs", root, "tmpfs", 0, nil) // chdir(root) - // After mounts, it will call: + // [do mounts] // mkdir("old_root") // pivot_root(root, "old_root") // umount("old_root", MNT_DETACH) @@ -74,6 +71,9 @@ type Runner struct { // mount("tmpfs", "/", "tmpfs", MS_BIND | MS_REMOUNT | MS_RDONLY | MS_NOATIME | MS_NOSUID, nil) PivotRoot string + // HostName and DomainName to be set after unshare UTS & user (CAP_SYS_ADMIN) + HostName, DomainName string + // drop_caps calls cap_set(self, 0) to drop all capabilities // from effective, permitted, inheritable capability sets before execve // it should avoid calls to set ambient capabilities diff --git a/pkg/mount/builder.go b/pkg/mount/builder.go new file mode 100644 index 0000000..6d4e93d --- /dev/null +++ b/pkg/mount/builder.go @@ -0,0 +1,90 @@ +package mount + +import ( + "os" + + "golang.org/x/sys/unix" +) + +const ( + bind = unix.MS_BIND | unix.MS_NOSUID | unix.MS_NOATIME | unix.MS_PRIVATE + roBind = bind | unix.MS_RDONLY + mFlag = unix.MS_NOSUID | unix.MS_NOATIME | unix.MS_NODEV | unix.MS_PRIVATE +) + +// Builder builds fork_exec friendly mount syscall format +type Builder struct { + Mounts []Mount +} + +// NewBuilder creates new mount builder instance +func NewBuilder() *Builder { + return &Builder{} +} + +// Build creates sequence of syscalls for fork_exec +// skipNotExists skips bind mounts that source not exitst +func (b *Builder) Build(skipNotExists bool) ([]SyscallParams, error) { + ret := make([]SyscallParams, 0, len(b.Mounts)) + for _, m := range b.Mounts { + if err := isBindMountNotExists(m); err != nil { + if skipNotExists { + continue + } + return nil, err + } + sp, err := m.ToSyscall() + if err != nil { + return nil, err + } + ret = append(ret, *sp) + } + return ret, nil +} + +func isBindMountNotExists(m Mount) error { + if m.Flags&unix.MS_BIND == unix.MS_BIND { + if _, err := os.Stat(m.Source); os.IsNotExist(err) { + return err + } + } + return nil +} + +// WithMounts add mounts to builder +func (b *Builder) WithMounts(m []Mount) *Builder { + b.Mounts = append(b.Mounts, m...) + return b +} + +// WithMount add single mount to builder +func (b *Builder) WithMount(m Mount) *Builder { + b.Mounts = append(b.Mounts, m) + return b +} + +// WithBind adds a bind mount to builder +func (b *Builder) WithBind(source, target string, readonly bool) *Builder { + var flags uintptr = bind + if readonly { + flags = roBind + } + b.Mounts = append(b.Mounts, Mount{ + Source: source, + Target: target, + Flags: flags, + }) + return b +} + +// WithTmpfs add a tmpfs mount to builder +func (b *Builder) WithTmpfs(target, data string) *Builder { + b.Mounts = append(b.Mounts, Mount{ + Source: "tmpfs", + Target: target, + FsType: "tmpfs", + Flags: mFlag, + Data: data, + }) + return b +} diff --git a/pkg/mount/mount.go b/pkg/mount/mount.go index a85c6e0..dde4079 100644 --- a/pkg/mount/mount.go +++ b/pkg/mount/mount.go @@ -1,7 +1,6 @@ package mount import ( - "os" "syscall" ) @@ -15,6 +14,7 @@ type Mount struct { type SyscallParams struct { Source, Target, FsType, Data *byte Flags uintptr + Prefixes []*byte } // ToSyscall convert Mount to SyscallPrams @@ -38,53 +38,42 @@ func (m *Mount) ToSyscall() (*SyscallParams, error) { return nil, err } } + prefix := pathPrefix(m.Target) + paths, err := arrayPtrFromStrings(prefix) + if err != nil { + return nil, err + } return &SyscallParams{ - Source: source, - Target: target, - FsType: fsType, - Flags: m.Flags, - Data: data, + Source: source, + Target: target, + FsType: fsType, + Flags: m.Flags, + Data: data, + Prefixes: paths, }, nil } -// Mount calls mount syscall -func (m *Mount) Mount() error { - if err := os.MkdirAll(m.Target, 0755); err != nil { - return err - } - if err := syscall.Mount(m.Source, m.Target, m.FsType, m.Flags, m.Data); err != nil { - return err - } - // Read-only bind mount need to be remounted - const bindRo = syscall.MS_BIND | syscall.MS_RDONLY - if m.Flags&bindRo == bindRo { - if err := syscall.Mount("", m.Target, m.FsType, m.Flags|syscall.MS_REMOUNT, m.Data); err != nil { - return err +// pathPrefix get all components from path +func pathPrefix(path string) []string { + ret := make([]string, 0) + for i := 1; i < len(path); i++ { + if path[i] == '/' { + ret = append(ret, path[:i]) } } - return nil + ret = append(ret, path) + return ret } -// ToSyscalls converts arrays of Mounts into SyscallParams -func ToSyscalls(ms []*Mount) ([]*SyscallParams, error) { - ret := make([]*SyscallParams, 0, len(ms)) - for _, m := range ms { - sp, err := m.ToSyscall() +// arrayPtrFromStrings converts srings to c style strings +func arrayPtrFromStrings(strs []string) ([]*byte, error) { + bytes := make([]*byte, 0, len(strs)) + for _, s := range strs { + b, err := syscall.BytePtrFromString(s) if err != nil { return nil, err } - ret = append(ret, sp) + bytes = append(bytes, b) } - return ret, nil -} - -// Mounts calls multiple mount syscalls -func Mounts(ms []*Mount) error { - for _, m := range ms { - err := m.Mount() - if err != nil { - return err - } - } - return nil + return bytes, nil } diff --git a/pkg/mount/mount_linux.go b/pkg/mount/mount_linux.go new file mode 100644 index 0000000..7f16e85 --- /dev/null +++ b/pkg/mount/mount_linux.go @@ -0,0 +1,24 @@ +package mount + +import ( + "os" + "syscall" +) + +// Mount calls mount syscall +func (m *Mount) Mount() error { + if err := os.MkdirAll(m.Target, 0755); err != nil { + return err + } + if err := syscall.Mount(m.Source, m.Target, m.FsType, m.Flags, m.Data); err != nil { + return err + } + // Read-only bind mount need to be remounted + const bindRo = syscall.MS_BIND | syscall.MS_RDONLY + if m.Flags&bindRo == bindRo { + if err := syscall.Mount("", m.Target, m.FsType, m.Flags|syscall.MS_REMOUNT, m.Data); err != nil { + return err + } + } + return nil +} diff --git a/pkg/rlimit/rlimit.go b/pkg/rlimit/rlimit.go index ccefca6..efca96f 100644 --- a/pkg/rlimit/rlimit.go +++ b/pkg/rlimit/rlimit.go @@ -8,10 +8,10 @@ import ( type RLimits struct { CPU uint64 // in s CPUHard uint64 // in s - Data uint64 // in kb - FileSize uint64 // in kb - Stack uint64 // in kb - AddressSpace uint64 // in kb + Data uint64 // in bytes + FileSize uint64 // in bytes + Stack uint64 // in bytes + AddressSpace uint64 // in bytes } // RLimit is the resource limits defined by Linux setrlimit @@ -23,7 +23,7 @@ type RLimit struct { } func getRlimit(cur, max uint64) syscall.Rlimit { - return syscall.Rlimit{Cur: uint64(cur), Max: uint64(max)} + return syscall.Rlimit{Cur: cur, Max: max} } // PrepareRLimit creates rlimit structures for tracee @@ -44,25 +44,25 @@ func (r *RLimits) PrepareRLimit() []RLimit { if r.Data > 0 { ret = append(ret, RLimit{ Res: syscall.RLIMIT_DATA, - Rlim: getRlimit(r.Data<<10, r.Data<<10), + Rlim: getRlimit(r.Data, r.Data), }) } if r.FileSize > 0 { ret = append(ret, RLimit{ Res: syscall.RLIMIT_FSIZE, - Rlim: getRlimit(r.FileSize<<10, r.FileSize<<10), + Rlim: getRlimit(r.FileSize, r.FileSize), }) } if r.Stack > 0 { ret = append(ret, RLimit{ Res: syscall.RLIMIT_STACK, - Rlim: getRlimit(r.Stack<<10, r.Stack<<10), + Rlim: getRlimit(r.Stack, r.Stack), }) } if r.AddressSpace > 0 { ret = append(ret, RLimit{ Res: syscall.RLIMIT_AS, - Rlim: getRlimit(r.AddressSpace<<10, r.AddressSpace<<10), + Rlim: getRlimit(r.AddressSpace, r.AddressSpace), }) } return ret diff --git a/runner/ptrace/run.go b/runner/ptrace/run.go index 8157226..0e5c707 100644 --- a/runner/ptrace/run.go +++ b/runner/ptrace/run.go @@ -12,7 +12,7 @@ func (r *Runner) Start(done <-chan struct{}) (<-chan types.Result, error) { Args: r.Args, Env: r.Env, ExecFile: r.ExecFile, - RLimits: r.RLimits.PrepareRLimit(), + RLimits: r.RLimits, Files: r.Files, WorkDir: r.WorkDir, Seccomp: r.Seccomp.SockFprog(), diff --git a/runner/ptrace/runner.go b/runner/ptrace/runner.go index fa82a5c..306857f 100644 --- a/runner/ptrace/runner.go +++ b/runner/ptrace/runner.go @@ -24,7 +24,7 @@ type Runner struct { Files []uintptr // Resource limit set by set rlimit - RLimits rlimit.RLimits + RLimits []rlimit.RLimit // Res limit enforced by tracer Limit types.Limit diff --git a/runner/unshare/default.go b/runner/unshare/default.go index a399436..b9c8f1a 100644 --- a/runner/unshare/default.go +++ b/runner/unshare/default.go @@ -1,36 +1,16 @@ package unshare import ( - "os" - "golang.org/x/sys/unix" "github.com/criyle/go-sandbox/pkg/mount" ) -// AddBind is the additional bind mounts besides the default one -type AddBind struct { - Source, Target string - ReadOnly bool -} +const roBind = unix.MS_BIND | unix.MS_NOSUID | unix.MS_PRIVATE | unix.MS_RDONLY -const ( - bind2 = unix.MS_BIND | unix.MS_NOSUID | unix.MS_NOATIME | unix.MS_NODEV | unix.MS_NODIRATIME - bind = unix.MS_BIND | unix.MS_NOSUID | unix.MS_PRIVATE - roBind = bind | unix.MS_RDONLY - noExecRoBind = roBind | unix.MS_NOEXEC - remountRo = unix.MS_REMOUNT | unix.MS_RDONLY -) - -// default parameters. I was tend to reuse the configs but it is hard since there are some -// cross device symblics var ( - DefaultMounts = []*mount.Mount{ - { - Source: "/usr/lib/locale", - Target: "usr/lib/locale", - Flags: roBind, - }, + // DefaultMounts is a example of minimal rootfs + DefaultMounts = []mount.Mount{ { Source: "/usr", Target: "usr", @@ -53,26 +33,3 @@ var ( }, } ) - -// GetDefaultMounts returns default mount parameters for given root -func GetDefaultMounts(root string, add []AddBind) []*mount.Mount { - mounts := make([]*mount.Mount, 0, len(DefaultMounts)+len(add)) - // check if bind mount source exists, e.g. /lib64 does not exists on arm - for _, m := range DefaultMounts { - if _, err := os.Stat(m.Source); !os.IsNotExist(err) { - mounts = append(mounts, m) - } - } - for _, m := range add { - flags := bind - if m.ReadOnly { - flags = roBind - } - mounts = append(mounts, &mount.Mount{ - Source: m.Source, - Target: m.Target, - Flags: uintptr(flags), - }) - } - return mounts -} diff --git a/runner/unshare/run.go b/runner/unshare/run.go index 14053a5..53ecfc2 100644 --- a/runner/unshare/run.go +++ b/runner/unshare/run.go @@ -23,7 +23,7 @@ func (r *Runner) Start(done <-chan struct{}) (<-chan types.Result, error) { Args: r.Args, Env: r.Env, ExecFile: r.ExecFile, - RLimits: r.RLimits.PrepareRLimit(), + RLimits: r.RLimits, Files: r.Files, WorkDir: r.WorkDir, Seccomp: r.Seccomp.SockFprog(), diff --git a/runner/unshare/runner.go b/runner/unshare/runner.go index 5755991..b0dac89 100644 --- a/runner/unshare/runner.go +++ b/runner/unshare/runner.go @@ -23,7 +23,7 @@ type Runner struct { Files []uintptr // Resource limit set by set rlimit - RLimits rlimit.RLimits + RLimits []rlimit.RLimit // Resource limit enforced by tracer Limit types.Limit @@ -35,7 +35,7 @@ type Runner struct { Root string // Mount syscalls - Mounts []*mount.Mount + Mounts []mount.SyscallParams // hostname & domainname HostName, DomainName string