diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go index cb9af7d7..29f5b26e 100644 --- a/libcontainer/setns_init_linux.go +++ b/libcontainer/setns_init_linux.go @@ -29,6 +29,11 @@ func (l *linuxSetnsInit) Init() error { if err := setOomScoreAdj(l.config.Config.OomScoreAdj); err != nil { return err } + if l.config.Config.NoNewPrivileges { + if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { + return err + } + } if l.config.Config.Seccomp != nil { if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil { return err diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index c17031dc..6240347a 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -21,6 +21,10 @@ type linuxStandardInit struct { config *initConfig } +// PR_SET_NO_NEW_PRIVS isn't exposed in Golang so we define it ourselves copying the value +// the kernel +const PR_SET_NO_NEW_PRIVS = 0x26 + func (l *linuxStandardInit) Init() error { // do not inherit the parent's session keyring sessKeyId, err := keyctl.JoinSessionKeyring("") @@ -103,6 +107,11 @@ func (l *linuxStandardInit) Init() error { if err != nil { return err } + if l.config.Config.NoNewPrivileges { + if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { + return err + } + } // Tell our parent that we're ready to Execv. This must be done before the // Seccomp rules have been applied, because we need to be able to read and // write to a socket. @@ -128,5 +137,6 @@ func (l *linuxStandardInit) Init() error { if syscall.Getppid() != l.parentPid { return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) } + return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) } diff --git a/libcontainer/system/linux.go b/libcontainer/system/linux.go index 6c835e68..babf5504 100644 --- a/libcontainer/system/linux.go +++ b/libcontainer/system/linux.go @@ -112,3 +112,11 @@ func RunningInUserNS() bool { } return true } + +func Prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) { + _, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0) + if e1 != 0 { + err = e1 + } + return +}