summaryrefslogtreecommitdiff
path: root/pkg/util
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/util')
-rw-r--r--pkg/util/mountOpts.go24
-rw-r--r--pkg/util/mountOpts_linux.go23
-rw-r--r--pkg/util/mountOpts_other.go7
-rw-r--r--pkg/util/utils.go43
-rw-r--r--pkg/util/utils_test.go12
5 files changed, 98 insertions, 11 deletions
diff --git a/pkg/util/mountOpts.go b/pkg/util/mountOpts.go
index d21800bc3..329a7c913 100644
--- a/pkg/util/mountOpts.go
+++ b/pkg/util/mountOpts.go
@@ -13,19 +13,17 @@ var (
ErrDupeMntOption = errors.Errorf("duplicate mount option passed")
)
-// DefaultMountOptions sets default mount options for ProcessOptions.
-type DefaultMountOptions struct {
- Noexec bool
- Nosuid bool
- Nodev bool
+type defaultMountOptions struct {
+ noexec bool
+ nosuid bool
+ nodev bool
}
// ProcessOptions parses the options for a bind or tmpfs mount and ensures that
// they are sensible and follow convention. The isTmpfs variable controls
// whether extra, tmpfs-specific options will be allowed.
-// The defaults variable controls default mount options that will be set. If it
-// is not included, they will be set unconditionally.
-func ProcessOptions(options []string, isTmpfs bool, defaults *DefaultMountOptions) ([]string, error) {
+// The sourcePath variable, if not empty, contains a bind mount source.
+func ProcessOptions(options []string, isTmpfs bool, sourcePath string) ([]string, error) {
var (
foundWrite, foundSize, foundProp, foundMode, foundExec, foundSuid, foundDev, foundCopyUp, foundBind, foundZ bool
)
@@ -122,13 +120,17 @@ func ProcessOptions(options []string, isTmpfs bool, defaults *DefaultMountOption
if !foundProp {
newOptions = append(newOptions, "rprivate")
}
- if !foundExec && (defaults == nil || defaults.Noexec) {
+ defaults, err := getDefaultMountOptions(sourcePath)
+ if err != nil {
+ return nil, err
+ }
+ if !foundExec && defaults.noexec {
newOptions = append(newOptions, "noexec")
}
- if !foundSuid && (defaults == nil || defaults.Nosuid) {
+ if !foundSuid && defaults.nosuid {
newOptions = append(newOptions, "nosuid")
}
- if !foundDev && (defaults == nil || defaults.Nodev) {
+ if !foundDev && defaults.nodev {
newOptions = append(newOptions, "nodev")
}
if isTmpfs && !foundCopyUp {
diff --git a/pkg/util/mountOpts_linux.go b/pkg/util/mountOpts_linux.go
new file mode 100644
index 000000000..3eac4dd25
--- /dev/null
+++ b/pkg/util/mountOpts_linux.go
@@ -0,0 +1,23 @@
+package util
+
+import (
+ "os"
+
+ "golang.org/x/sys/unix"
+)
+
+func getDefaultMountOptions(path string) (defaultMountOptions, error) {
+ opts := defaultMountOptions{true, true, true}
+ if path == "" {
+ return opts, nil
+ }
+ var statfs unix.Statfs_t
+ if e := unix.Statfs(path, &statfs); e != nil {
+ return opts, &os.PathError{Op: "statfs", Path: path, Err: e}
+ }
+ opts.nodev = (statfs.Flags&unix.MS_NODEV == unix.MS_NODEV)
+ opts.noexec = (statfs.Flags&unix.MS_NOEXEC == unix.MS_NOEXEC)
+ opts.nosuid = (statfs.Flags&unix.MS_NOSUID == unix.MS_NOSUID)
+
+ return opts, nil
+}
diff --git a/pkg/util/mountOpts_other.go b/pkg/util/mountOpts_other.go
new file mode 100644
index 000000000..6a34942e5
--- /dev/null
+++ b/pkg/util/mountOpts_other.go
@@ -0,0 +1,7 @@
+// +build !linux
+
+package util
+
+func getDefaultMountOptions(path string) (opts defaultMountOptions, err error) {
+ return
+}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 3e11c010a..0c055745d 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -609,3 +609,46 @@ func Tmpdir() string {
return tmpdir
}
+
+// ValidateSysctls validates a list of sysctl and returns it.
+func ValidateSysctls(strSlice []string) (map[string]string, error) {
+ sysctl := make(map[string]string)
+ validSysctlMap := map[string]bool{
+ "kernel.msgmax": true,
+ "kernel.msgmnb": true,
+ "kernel.msgmni": true,
+ "kernel.sem": true,
+ "kernel.shmall": true,
+ "kernel.shmmax": true,
+ "kernel.shmmni": true,
+ "kernel.shm_rmid_forced": true,
+ }
+ validSysctlPrefixes := []string{
+ "net.",
+ "fs.mqueue.",
+ }
+
+ for _, val := range strSlice {
+ foundMatch := false
+ arr := strings.Split(val, "=")
+ if len(arr) < 2 {
+ return nil, errors.Errorf("%s is invalid, sysctl values must be in the form of KEY=VALUE", val)
+ }
+ if validSysctlMap[arr[0]] {
+ sysctl[arr[0]] = arr[1]
+ continue
+ }
+
+ for _, prefix := range validSysctlPrefixes {
+ if strings.HasPrefix(arr[0], prefix) {
+ sysctl[arr[0]] = arr[1]
+ foundMatch = true
+ break
+ }
+ }
+ if !foundMatch {
+ return nil, errors.Errorf("sysctl '%s' is not whitelisted", arr[0])
+ }
+ }
+ return sysctl, nil
+}
diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go
index 0995d1e20..a9b37844e 100644
--- a/pkg/util/utils_test.go
+++ b/pkg/util/utils_test.go
@@ -245,3 +245,15 @@ func TestGetImageConfigMisc(t *testing.T) {
_, err = GetImageConfig([]string{"BADINST testvalue"})
assert.NotNil(t, err)
}
+
+func TestValidateSysctls(t *testing.T) {
+ strSlice := []string{"net.core.test1=4", "kernel.msgmax=2"}
+ result, _ := ValidateSysctls(strSlice)
+ assert.Equal(t, result["net.core.test1"], "4")
+}
+
+func TestValidateSysctlBadSysctl(t *testing.T) {
+ strSlice := []string{"BLAU=BLUE", "GELB^YELLOW"}
+ _, err := ValidateSysctls(strSlice)
+ assert.Error(t, err)
+}