From 01355dca0b9cd806980308d0286afd14af40b792 Mon Sep 17 00:00:00 2001 From: haosanzi Date: Fri, 11 Sep 2020 20:36:29 +0800 Subject: [PATCH] rune/libcontainer/spec_linux: Conditionally mount aesmd and add enclave devices to the whitelist In addition, move enclave-specific code into libenclave. Signed-off-by: Shirong Hao shirong@linux.alibaba.com --- rune/libcontainer/specconv/spec_linux.go | 137 +------------------ rune/libenclave/check.go | 159 +++++++++++++++++++++++ 2 files changed, 166 insertions(+), 130 deletions(-) create mode 100644 rune/libenclave/check.go diff --git a/rune/libcontainer/specconv/spec_linux.go b/rune/libcontainer/specconv/spec_linux.go index 901903b..cf8864c 100644 --- a/rune/libcontainer/specconv/spec_linux.go +++ b/rune/libcontainer/specconv/spec_linux.go @@ -17,13 +17,12 @@ import ( dbus "github.com/godbus/dbus/v5" "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" - "github.com/opencontainers/runc/libcontainer/devices" "github.com/opencontainers/runc/libcontainer/seccomp" libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils" + "github.com/opencontainers/runc/libenclave" "github.com/opencontainers/runc/libenclave/attestation/sgx" "github.com/opencontainers/runc/libenclave/intelsgx" "github.com/opencontainers/runtime-spec/specs-go" - "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -203,12 +202,15 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) { createEnclaveConfig(spec, config) exists := false + for _, m := range spec.Mounts { config.Mounts = append(config.Mounts, createLibcontainerMount(cwd, m)) } + if config.Enclave != nil { - config.Mounts = append(config.Mounts, createLibenclaveMount(cwd)) + libenclave.CreateLibenclaveMount(cwd, config) } + if err := createDevices(spec, config); err != nil { return nil, err } @@ -393,104 +395,6 @@ func createEnclaveConfig(spec *specs.Spec, config *configs.Config) { } } -// Determine whether the device is a Intel SGX enclave device -func intelSgxDev(device *configs.Device) (*configs.Device, error) { - dev, err := devices.DeviceFromPath(device.Path, "rwm") - if err != nil { - return nil, err - } - - if dev.Type == 'c' && dev.Major == 10 { - return dev, nil - } - - return nil, fmt.Errorf("%s is not a SGX enclave device", dev.Path) -} - -func createEnclaveDevices(devs []*configs.Device, etype string, fn func(dev *configs.Device)) { - var configuredDevs []string - - // Retrieve the configured enclave devices - onMatchEnclaveDevice(devs, genEnclavePathTemplate(etype), etype, func(n string, i int) { - configuredDevs = append(configuredDevs, n) - }) - - if len(configuredDevs) != 0 { - for _, d := range configuredDevs { - dev, err := devices.DeviceFromPath(d, "rwm") - if err != nil { - logrus.Debugf("the configured enclave device %s not exist", dev.Path) - continue - } - - logrus.Debugf("the enclave device %s configured", dev.Path) - } - } - - // Filter out the configured enclave devices - exclusiveDevs := genEnclaveDeviceTemplate(etype) - onMatchEnclaveDevice(exclusiveDevs, configuredDevs, etype, func(n string, i int) { - exclusiveDevs = append(exclusiveDevs[:i], exclusiveDevs[i+1:]...) - }) - - // Create the enclave devices not explicitly specified - for _, d := range exclusiveDevs { - dev, err := intelSgxDev(d) - if err != nil { - continue - } - - fn(dev) - } -} - -func genEnclavePathTemplate(etype string) []string { - switch etype { - case configs.EnclaveHwIntelSgx: - return []string{"/dev/isgx", "/dev/sgx/enclave", "/dev/gsgx"} - default: - return nil - } -} - -func genEnclaveDeviceTemplate(etype string) []*configs.Device { - switch etype { - case configs.EnclaveHwIntelSgx: - return []*configs.Device{ - &configs.Device{ - Type: 'c', - Path: "/dev/isgx", - Major: 10, - }, - &configs.Device{ - Type: 'c', - Path: "/dev/sgx/enclave", - Major: 10, - }, - &configs.Device{ - Type: 'c', - Path: "/dev/gsgx", - Major: 10, - }, - } - default: - return nil - } -} - -func onMatchEnclaveDevice(devices []*configs.Device, names []string, etype string, fn func(n string, i int)) { - switch etype { - case configs.EnclaveHwIntelSgx: - for _, n := range names { - for i, dev := range devices { - if dev.Path == n { - fn(n, i) - } - } - } - } -} - func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount { flags, pgflags, data, ext := parseMountOptions(m.Options) source := m.Source @@ -515,16 +419,6 @@ func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount { } } -func createLibenclaveMount(cwd string) *configs.Mount { - return &configs.Mount{ - Device: "bind", - Source: "/var/run/aesmd", - Destination: "/var/run/aesmd", - Flags: unix.MS_BIND | unix.MS_REC, - PropagationFlags: []int{unix.MS_PRIVATE | unix.MS_REC}, - } -} - // systemd property name check: latin letters only, at least 3 of them var isValidName = regexp.MustCompile(`^[a-zA-Z]{3,}$`).MatchString @@ -803,19 +697,11 @@ func CreateCgroupConfig(opts *CreateOpts, config *configs.Config) (*configs.Cgro // append the default allowed devices to the end of the list c.Resources.Devices = append(c.Resources.Devices, AllowedDevices...) if config.Enclave != nil { - createEnclaveCgroupConfig(&c.Resources.Devices, config.Enclave.Type) + libenclave.CreateEnclaveCgroupConfig(&c.Resources.Devices, config.Enclave.Type) } return c, nil } -func createEnclaveCgroupConfig(devices *[]*configs.Device, etype string) { - createEnclaveDevices(*devices, etype, func(dev *configs.Device) { - dev.Permissions = "rwm" - dev.Allow = true - *devices = append(*devices, dev) - }) -} - func stringToCgroupDeviceRune(s string) (rune, error) { switch s { case "a": @@ -934,20 +820,11 @@ func createDevices(spec *specs.Spec, config *configs.Config) error { } } if config.Enclave != nil { - createEnclaveDeviceConfig(&config.Devices, config.Enclave.Type) + libenclave.CreateEnclaveDeviceConfig(&config.Devices, config.Enclave.Type) } return nil } -func createEnclaveDeviceConfig(devices *[]*configs.Device, etype string) { - createEnclaveDevices(*devices, etype, func(dev *configs.Device) { - dev.FileMode = 0666 - dev.Uid = 0 - dev.Gid = 0 - *devices = append(*devices, dev) - }) -} - func setupUserNamespace(spec *specs.Spec, config *configs.Config) error { create := func(m specs.LinuxIDMapping) configs.IDMap { return configs.IDMap{ diff --git a/rune/libenclave/check.go b/rune/libenclave/check.go new file mode 100644 index 0000000..620c999 --- /dev/null +++ b/rune/libenclave/check.go @@ -0,0 +1,159 @@ +package libenclave // import "github.com/opencontainers/runc/libenclave" + +import ( + "fmt" + "strings" + + "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/devices" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" +) + +func createLibenclaveMount(cwd string) *configs.Mount { + return &configs.Mount{ + Device: "bind", + Source: "/var/run/aesmd", + Destination: "/var/run/aesmd", + Flags: unix.MS_BIND | unix.MS_REC, + PropagationFlags: []int{unix.MS_PRIVATE | unix.MS_REC}, + } +} + +func CreateLibenclaveMount(cwd string, config *configs.Config) { + aesmedMounted := false + for _, m := range config.Mounts { + if strings.EqualFold(m.Destination, "/var/run/aesmd") || strings.EqualFold(m.Destination, "/run/aesmd") { + aesmedMounted = true + break + } + } + if aesmedMounted != true { + config.Mounts = append(config.Mounts, createLibenclaveMount(cwd)) + } +} + +func CreateEnclaveCgroupConfig(devices *[]*configs.Device, etype string) { + createEnclaveDevices(*devices, etype, func(dev *configs.Device) { + dev.Permissions = "rwm" + dev.Allow = true + *devices = append(*devices, dev) + }) +} + +// Determine whether the device is a Intel SGX enclave device +func intelSgxDev(device *configs.Device) (*configs.Device, error) { + dev, err := devices.DeviceFromPath(device.Path, "rwm") + if err != nil { + return nil, err + } + + if dev.Type == 'c' && dev.Major == 10 { + return dev, nil + } + + return nil, fmt.Errorf("%s is not a SGX enclave device", dev.Path) +} + +func createEnclaveDevices(devs []*configs.Device, etype string, fn func(dev *configs.Device)) { + var configuredDevs []string + // Retrieve the configured enclave devices + onMatchEnclaveDevice(devs, genEnclavePathTemplate(etype), etype, func(n string, i int) { + configuredDevs = append(configuredDevs, n) + }) + + if len(configuredDevs) != 0 { + for _, d := range configuredDevs { + dev, err := devices.DeviceFromPath(d, "rwm") + if err != nil { + logrus.Debugf("the configured enclave device %s not exist", dev.Path) + continue + } + + logrus.Debugf("the enclave device %s configured", dev.Path) + } + } + + // Filter out the configured enclave devices + exclusiveDevs := genEnclaveDeviceTemplate(etype) + + onMatchEnclaveDevice(exclusiveDevs, configuredDevs, etype, func(n string, i int) { + exclusiveDevs = append(exclusiveDevs[:i], exclusiveDevs[i+1:]...) + }) + + // Create the enclave devices not explicitly specified + for _, d := range exclusiveDevs { + dev, err := intelSgxDev(d) + if err != nil { + continue + } + if !containEnclaveDevice(devs, dev.Path) { + fn(dev) + } + } +} + +func onMatchEnclaveDevice(devices []*configs.Device, names []string, etype string, fn func(n string, i int)) { + switch etype { + case configs.EnclaveHwIntelSgx: + for _, n := range names { + for i, dev := range devices { + if dev.Path == n { + fn(n, i) + } + } + } + } +} + +func genEnclaveDeviceTemplate(etype string) []*configs.Device { + switch etype { + case configs.EnclaveHwIntelSgx: + return []*configs.Device{ + &configs.Device{ + Type: 'c', + Path: "/dev/isgx", + Major: 10, + }, + &configs.Device{ + Type: 'c', + Path: "/dev/sgx/enclave", + Major: 10, + }, + &configs.Device{ + Type: 'c', + Path: "/dev/gsgx", + Major: 10, + }, + } + default: + return nil + } +} + +func containEnclaveDevice(devices []*configs.Device, s string) bool { + for _, c := range devices { + if c.Path == s { + return true + } + } + return false +} + +func genEnclavePathTemplate(etype string) []string { + switch etype { + case configs.EnclaveHwIntelSgx: + return []string{"/dev/isgx", "/dev/sgx/enclave", "/dev/gsgx"} + default: + return nil + } +} + +func CreateEnclaveDeviceConfig(devices *[]*configs.Device, etype string) { + createEnclaveDevices(*devices, etype, func(dev *configs.Device) { + dev.FileMode = 0666 + dev.Uid = 0 + dev.Gid = 0 + *devices = append(*devices, dev) + }) +} -- GitLab