Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Commit

Permalink
Merge pull request #375 from crosbymichael/move-system-mounts
Browse files Browse the repository at this point in the history
Refactor system mounts to be placed on the config
  • Loading branch information
vmarmol committed Feb 13, 2015
2 parents a9a5030 + 1a37242 commit 031524c
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 158 deletions.
12 changes: 8 additions & 4 deletions configs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,6 @@ type Config struct {
// commonly used by selinux
ProcessLabel string `json:"process_label"`

// RestrictSys will remount /proc/sys, /sys, and mask over sysrq-trigger as well as /proc/irq and
// /proc/bus
RestrictSys bool `json:"restrict_sys"`

// Rlimits specifies the resource limits, such as max open files, to set in the container
// If Rlimits are not set, the container will inherit rlimits from the parent process
Rlimits []Rlimit `json:"rlimits"`
Expand All @@ -95,6 +91,14 @@ type Config struct {

// GidMappings is an array of Group ID mappings for User Namespaces
GidMappings []IDMap `json:"gid_mappings"`

// MaskPaths specifies paths within the container's rootfs to mask over with a bind
// mount pointing to /dev/null as to prevent reads of the file.
MaskPaths []string `json:"mask_paths"`

// ReadonlyPaths specifies paths within the container's rootfs to remount as read-only
// so that these files prevent any writes.
ReadonlyPaths []string `json:"readonly_paths"`
}

// Gets the root uid for the process on host which could be non-zero
Expand Down
6 changes: 0 additions & 6 deletions configs/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,12 @@ func TestConfigJsonFormat(t *testing.T) {
break
}
}

for _, d := range DefaultSimpleDevices {
if !containsDevice(d, container.Devices) {
t.Logf("expected device configuration for %s", d.Path)
t.Fail()
}
}

if !container.RestrictSys {
t.Log("expected restrict sys to be true")
t.Fail()
}
}

func TestApparmorProfile(t *testing.T) {
Expand Down
24 changes: 17 additions & 7 deletions configs/mount.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
package configs

type Mount struct {
Type string `json:"type"`
Source string `json:"source"` // Source path, in the host namespace
Destination string `json:"destination"` // Destination path, in the container
Writable bool `json:"writable"`
Relabel string `json:"relabel"` // Relabel source if set, "z" indicates shared, "Z" indicates unshared
Private bool `json:"private"`
Slave bool `json:"slave"`
// Source path for the mount.
Source string `json:"source"`

// Destination path for the mount inside the container.
Destination string `json:"destination"`

// Device the mount is for.
Device string `json:"device"`

// Mount flags.
Flags int `json:"flags"`

// Mount data applied to the mount.
Data string `json:"data"`

// Relabel source if set, "z" indicates shared, "Z" indicates unshared.
Relabel string `json:"relabel"`
}
3 changes: 2 additions & 1 deletion configs/validate/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ func (v *ConfigValidator) hostname(config *configs.Config) error {

func (v *ConfigValidator) security(config *configs.Config) error {
// restrict sys without mount namespace
if config.RestrictSys && !config.Namespaces.Contains(configs.NEWNS) {
if (len(config.MaskPaths) > 0 || len(config.ReadonlyPaths) > 0) &&
!config.Namespaces.Contains(configs.NEWNS) {
return fmt.Errorf("unable to restrict sys entries without a private MNT namespace")
}
return nil
Expand Down
30 changes: 29 additions & 1 deletion integration/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ var standardEnvironment = []string{
"TERM=xterm",
}

const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV

// newTemplateConfig returns a base template for running a container
//
// it uses a network strategy of just setting a loopback interface
Expand Down Expand Up @@ -49,9 +51,35 @@ func newTemplateConfig(rootfs string) *configs.Config {
AllowAllDevices: false,
AllowedDevices: configs.DefaultAllowedDevices,
},

MaskPaths: []string{
"/proc/kcore",
},
ReadonlyPaths: []string{
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
},
Devices: configs.DefaultAutoCreatedDevices,
Hostname: "integration",
Mounts: []*configs.Mount{
{
Device: "tmpfs",
Source: "shm",
Destination: "/dev/shm",
Data: "mode=1777,size=65536k",
Flags: defaultMountFlags,
},
{
Source: "mqueue",
Destination: "/dev/mqueue",
Device: "mqueue",
Flags: defaultMountFlags,
},
{
Source: "sysfs",
Destination: "/sys",
Device: "sysfs",
Flags: defaultMountFlags | syscall.MS_RDONLY,
},
},
Networks: []*configs.Network{
{
Type: "loopback",
Expand Down
Loading

0 comments on commit 031524c

Please sign in to comment.