Browse code

check seccomp is configured in the kernel

Signed-off-by: Jessica Frazelle <acidburn@docker.com>

Jessica Frazelle authored on 2016/01/12 04:44:34
Showing 5 changed files
... ...
@@ -242,6 +242,14 @@ func (daemon *Daemon) populateCommand(c *container.Container, env []string) erro
242 242
 	}
243 243
 	uidMap, gidMap := daemon.GetUIDGIDMaps()
244 244
 
245
+	if !daemon.seccompEnabled {
246
+		if c.SeccompProfile != "" && c.SeccompProfile != "unconfined" {
247
+			return fmt.Errorf("Seccomp is not enabled in your kernel, cannot run a custom seccomp profile.")
248
+		}
249
+		logrus.Warn("Seccomp is not enabled in your kernel, running container without default profile.")
250
+		c.SeccompProfile = "unconfined"
251
+	}
252
+
245 253
 	defaultCgroupParent := "/docker"
246 254
 	if daemon.configStore.CgroupParent != "" {
247 255
 		defaultCgroupParent = daemon.configStore.CgroupParent
... ...
@@ -157,6 +157,7 @@ type Daemon struct {
157 157
 	volumes                   *store.VolumeStore
158 158
 	discoveryWatcher          discovery.Watcher
159 159
 	root                      string
160
+	seccompEnabled            bool
160 161
 	shutdown                  bool
161 162
 	uidMaps                   []idtools.IDMap
162 163
 	gidMaps                   []idtools.IDMap
... ...
@@ -851,6 +852,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
851 851
 	d.root = config.Root
852 852
 	d.uidMaps = uidMaps
853 853
 	d.gidMaps = gidMaps
854
+	d.seccompEnabled = sysInfo.Seccomp
854 855
 
855 856
 	if err := d.cleanupMounts(); err != nil {
856 857
 		return nil, err
... ...
@@ -77,7 +77,7 @@ var (
77 77
 	}
78 78
 	seccompEnabled = testRequirement{
79 79
 		func() bool {
80
-			return supportsSeccomp
80
+			return supportsSeccomp && SysInfo.Seccomp
81 81
 		},
82 82
 		"Test requires that seccomp support be enabled in the daemon.",
83 83
 	}
... ...
@@ -7,6 +7,8 @@ import "github.com/docker/docker/pkg/parsers"
7 7
 type SysInfo struct {
8 8
 	// Whether the kernel supports AppArmor or not
9 9
 	AppArmor bool
10
+	// Whether the kernel supports Seccomp or not
11
+	Seccomp bool
10 12
 
11 13
 	cgroupMemInfo
12 14
 	cgroupCPUInfo
... ...
@@ -5,11 +5,17 @@ import (
5 5
 	"os"
6 6
 	"path"
7 7
 	"strings"
8
+	"syscall"
8 9
 
9 10
 	"github.com/Sirupsen/logrus"
10 11
 	"github.com/opencontainers/runc/libcontainer/cgroups"
11 12
 )
12 13
 
14
+const (
15
+	// SeccompModeFilter refers to the syscall argument SECCOMP_MODE_FILTER.
16
+	SeccompModeFilter = uintptr(2)
17
+)
18
+
13 19
 // New returns a new SysInfo, using the filesystem to detect which features
14 20
 // the kernel supports. If `quiet` is `false` warnings are printed in logs
15 21
 // whenever an error occurs or misconfigurations are present.
... ...
@@ -32,6 +38,14 @@ func New(quiet bool) *SysInfo {
32 32
 		sysInfo.AppArmor = true
33 33
 	}
34 34
 
35
+	// Check if Seccomp is supported, via CONFIG_SECCOMP.
36
+	if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_SECCOMP, 0, 0); err != syscall.EINVAL {
37
+		// Make sure the kernel has CONFIG_SECCOMP_FILTER.
38
+		if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_SECCOMP, SeccompModeFilter, 0); err != syscall.EINVAL {
39
+			sysInfo.Seccomp = true
40
+		}
41
+	}
42
+
35 43
 	return sysInfo
36 44
 }
37 45