Create a new session key for every container
Create a new session key ring '_ses' for every container. This avoids sharing the key structure with the process that created the container and the container inherits from. This patch fixes it init and exec. Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
This commit is contained in:
parent
79d3577743
commit
ad22e23aee
|
@ -0,0 +1,67 @@
|
||||||
|
// +build linux
|
||||||
|
|
||||||
|
package keyctl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
"strings"
|
||||||
|
"strconv"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const KEYCTL_JOIN_SESSION_KEYRING = 1
|
||||||
|
const KEYCTL_SETPERM = 5
|
||||||
|
const KEYCTL_DESCRIBE = 6
|
||||||
|
|
||||||
|
type KeySerial uint32
|
||||||
|
|
||||||
|
func JoinSessionKeyring(name string) (KeySerial, error) {
|
||||||
|
var _name *byte = nil
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if len(name) > 0 {
|
||||||
|
_name, err = syscall.BytePtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return KeySerial(0), err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sessKeyId, _, errn := syscall.Syscall(syscall.SYS_KEYCTL, KEYCTL_JOIN_SESSION_KEYRING, uintptr(unsafe.Pointer(_name)), 0)
|
||||||
|
if errn != 0 {
|
||||||
|
return 0, fmt.Errorf("could not create session key: %v", errn)
|
||||||
|
}
|
||||||
|
return KeySerial(sessKeyId), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// modify permissions on a keyring by reading the current permissions,
|
||||||
|
// anding the bits with the given mask (clearing permissions) and setting
|
||||||
|
// additional permission bits
|
||||||
|
func ModKeyringPerm(ringId KeySerial, mask, setbits uint32) error {
|
||||||
|
dest := make([]byte, 1024)
|
||||||
|
destBytes := unsafe.Pointer(&dest[0])
|
||||||
|
|
||||||
|
if _, _, err := syscall.Syscall6(syscall.SYS_KEYCTL, uintptr(KEYCTL_DESCRIBE), uintptr(ringId), uintptr(destBytes), uintptr(len(dest)), 0, 0); err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res := strings.Split(string(dest), ";")
|
||||||
|
if len(res) < 5 {
|
||||||
|
return fmt.Errorf("Destination buffer for key description is too small")
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse permissions
|
||||||
|
perm64, err := strconv.ParseUint(res[3], 16, 32)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
perm := (uint32(perm64) & mask) | setbits
|
||||||
|
|
||||||
|
if _, _, err := syscall.Syscall(syscall.SYS_KEYCTL, uintptr(KEYCTL_SETPERM), uintptr(ringId), uintptr(perm)); err != 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/opencontainers/runc/libcontainer/apparmor"
|
"github.com/opencontainers/runc/libcontainer/apparmor"
|
||||||
|
"github.com/opencontainers/runc/libcontainer/keys"
|
||||||
"github.com/opencontainers/runc/libcontainer/label"
|
"github.com/opencontainers/runc/libcontainer/label"
|
||||||
"github.com/opencontainers/runc/libcontainer/seccomp"
|
"github.com/opencontainers/runc/libcontainer/seccomp"
|
||||||
"github.com/opencontainers/runc/libcontainer/system"
|
"github.com/opencontainers/runc/libcontainer/system"
|
||||||
|
@ -18,6 +19,10 @@ type linuxSetnsInit struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *linuxSetnsInit) Init() error {
|
func (l *linuxSetnsInit) Init() error {
|
||||||
|
// do not inherit the parent's session keyring
|
||||||
|
if _, err := keyctl.JoinSessionKeyring("_ses"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if err := setupRlimits(l.config.Config); err != nil {
|
if err := setupRlimits(l.config.Config); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/opencontainers/runc/libcontainer/apparmor"
|
"github.com/opencontainers/runc/libcontainer/apparmor"
|
||||||
"github.com/opencontainers/runc/libcontainer/configs"
|
"github.com/opencontainers/runc/libcontainer/configs"
|
||||||
|
"github.com/opencontainers/runc/libcontainer/keys"
|
||||||
"github.com/opencontainers/runc/libcontainer/label"
|
"github.com/opencontainers/runc/libcontainer/label"
|
||||||
"github.com/opencontainers/runc/libcontainer/seccomp"
|
"github.com/opencontainers/runc/libcontainer/seccomp"
|
||||||
"github.com/opencontainers/runc/libcontainer/system"
|
"github.com/opencontainers/runc/libcontainer/system"
|
||||||
|
@ -21,6 +22,18 @@ type linuxStandardInit struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *linuxStandardInit) Init() error {
|
func (l *linuxStandardInit) Init() error {
|
||||||
|
// do not inherit the parent's session keyring
|
||||||
|
sessKeyId, err := keyctl.JoinSessionKeyring("")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// make session keyring searcheable
|
||||||
|
// without user ns we need 'UID' search permissions
|
||||||
|
// with user ns we need 'other' search permissions
|
||||||
|
if err := keyctl.ModKeyringPerm(sessKeyId, 0xffffffff, 0x080008); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// join any namespaces via a path to the namespace fd if provided
|
// join any namespaces via a path to the namespace fd if provided
|
||||||
if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil {
|
if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Reference in New Issue