Browse code

Seccomp Update

- Update libseccomp-golang to 0.9.0 release
- Update libseccomp to 2.3.2 release
- add preadv2 and pwritev2 syscalls to whitelist

Signed-off-by: Justin Cormack <justin.cormack@docker.com>

Justin Cormack authored on 2017/03/08 07:19:46
Showing 11 changed files
... ...
@@ -108,8 +108,8 @@ RUN set -x \
108 108
 	&& UNATTENDED=yes OSX_VERSION_MIN=10.6 ${OSXCROSS_PATH}/build.sh
109 109
 ENV PATH /osxcross/target/bin:$PATH
110 110
 
111
-# Install seccomp: the version shipped in trusty is too old
112
-ENV SECCOMP_VERSION 2.3.1
111
+# Install seccomp: the version shipped upstream is too old
112
+ENV SECCOMP_VERSION 2.3.2
113 113
 RUN set -x \
114 114
 	&& export SECCOMP_PATH="$(mktemp -d)" \
115 115
 	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
... ...
@@ -78,8 +78,8 @@ RUN cd /usr/local/lvm2 \
78 78
 	&& make install_device-mapper
79 79
 # See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
80 80
 
81
-# Install seccomp: the version shipped in trusty is too old
82
-ENV SECCOMP_VERSION 2.3.1
81
+# Install seccomp: the version shipped upstream is too old
82
+ENV SECCOMP_VERSION 2.3.2
83 83
 RUN set -x \
84 84
 	&& export SECCOMP_PATH="$(mktemp -d)" \
85 85
 	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
... ...
@@ -92,8 +92,8 @@ RUN git clone https://github.com/golang/lint.git /go/src/github.com/golang/lint
92 92
 	&& (cd /go/src/github.com/golang/lint && git checkout -q $GO_LINT_COMMIT) \
93 93
 	&& go install -v github.com/golang/lint/golint
94 94
 
95
-# Install seccomp: the version shipped in trusty is too old
96
-ENV SECCOMP_VERSION 2.3.1
95
+# Install seccomp: the version shipped upstream is too old
96
+ENV SECCOMP_VERSION 2.3.2
97 97
 RUN set -x \
98 98
 	&& export SECCOMP_PATH="$(mktemp -d)" \
99 99
 	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
... ...
@@ -77,8 +77,8 @@ RUN cd /usr/local/lvm2 \
77 77
 	&& make install_device-mapper
78 78
 # See https://git.fedorahosted.org/cgit/lvm2.git/tree/INSTALL
79 79
 
80
-# Install seccomp: the version shipped in jessie is too old
81
-ENV SECCOMP_VERSION 2.3.1
80
+# Install seccomp: the version shipped upstream is too old
81
+ENV SECCOMP_VERSION 2.3.2
82 82
 RUN set -x \
83 83
         && export SECCOMP_PATH="$(mktemp -d)" \
84 84
         && curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
... ...
@@ -50,8 +50,8 @@ RUN apt-get update && apt-get install -y \
50 50
 	vim-common \
51 51
 	--no-install-recommends
52 52
 
53
-# Install seccomp: the version shipped in jessie is too old
54
-ENV SECCOMP_VERSION 2.3.1
53
+# Install seccomp: the version shipped upstream is too old
54
+ENV SECCOMP_VERSION 2.3.2
55 55
 RUN set -x \
56 56
 	&& export SECCOMP_PATH="$(mktemp -d)" \
57 57
 	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
... ...
@@ -34,8 +34,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
34 34
 		vim-common \
35 35
 	&& rm -rf /var/lib/apt/lists/*
36 36
 
37
-# Install seccomp: the version shipped in trusty is too old
38
-ENV SECCOMP_VERSION 2.3.1
37
+# Install seccomp: the version shipped upstream is too old
38
+ENV SECCOMP_VERSION 2.3.2
39 39
 RUN set -x \
40 40
 	&& export SECCOMP_PATH="$(mktemp -d)" \
41 41
 	&& curl -fsSL "https://github.com/seccomp/libseccomp/releases/download/v${SECCOMP_VERSION}/libseccomp-${SECCOMP_VERSION}.tar.gz" \
... ...
@@ -223,10 +223,12 @@
223 223
 				"prctl",
224 224
 				"pread64",
225 225
 				"preadv",
226
+				"preadv2",
226 227
 				"prlimit64",
227 228
 				"pselect6",
228 229
 				"pwrite64",
229 230
 				"pwritev",
231
+				"pwritev2",
230 232
 				"read",
231 233
 				"readahead",
232 234
 				"readlink",
... ...
@@ -217,10 +217,12 @@ func DefaultProfile() *types.Seccomp {
217 217
 				"prctl",
218 218
 				"pread64",
219 219
 				"preadv",
220
+				"preadv2",
220 221
 				"prlimit64",
221 222
 				"pselect6",
222 223
 				"pwrite64",
223 224
 				"pwritev",
225
+				"pwritev2",
224 226
 				"read",
225 227
 				"readahead",
226 228
 				"readlink",
... ...
@@ -63,7 +63,7 @@ github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
63 63
 # When updating, also update RUNC_COMMIT in hack/dockerfile/binaries-commits accordingly
64 64
 github.com/opencontainers/runc a01dafd48bc1c7cc12bdb01206f9fea7dd6feb70 https://github.com/docker/runc.git # libcontainer
65 65
 github.com/opencontainers/runtime-spec 1c7c27d043c2a5e513a44084d2b10d77d1402b8c # specs
66
-github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
66
+github.com/seccomp/libseccomp-golang v0.9.0
67 67
 # libcontainer deps (see src/github.com/opencontainers/runc/Godeps/Godeps.json)
68 68
 github.com/coreos/go-systemd v4
69 69
 github.com/godbus/dbus v4.0.0
... ...
@@ -27,6 +27,28 @@ import "C"
27 27
 
28 28
 // Exported types
29 29
 
30
+// VersionError denotes that the system libseccomp version is incompatible
31
+// with this package.
32
+type VersionError struct {
33
+	message string
34
+	minimum string
35
+}
36
+
37
+func (e VersionError) Error() string {
38
+	format := "Libseccomp version too low: "
39
+	if e.message != "" {
40
+		format += e.message + ": "
41
+	}
42
+	format += "minimum supported is "
43
+	if e.minimum != "" {
44
+		format += e.minimum + ": "
45
+	} else {
46
+		format += "2.1.0: "
47
+	}
48
+	format += "detected %d.%d.%d"
49
+	return fmt.Sprintf(format, verMajor, verMinor, verMicro)
50
+}
51
+
30 52
 // ScmpArch represents a CPU architecture. Seccomp can restrict syscalls on a
31 53
 // per-architecture basis.
32 54
 type ScmpArch uint
... ...
@@ -151,6 +173,10 @@ const (
151 151
 // GetArchFromString returns an ScmpArch constant from a string representing an
152 152
 // architecture
153 153
 func GetArchFromString(arch string) (ScmpArch, error) {
154
+	if err := ensureSupportedVersion(); err != nil {
155
+		return ArchInvalid, err
156
+	}
157
+
154 158
 	switch strings.ToLower(arch) {
155 159
 	case "x86":
156 160
 		return ArchX86, nil
... ...
@@ -338,6 +364,10 @@ func (s ScmpSyscall) GetNameByArch(arch ScmpArch) (string, error) {
338 338
 // Returns the number of the syscall, or an error if no syscall with that name
339 339
 // was found.
340 340
 func GetSyscallFromName(name string) (ScmpSyscall, error) {
341
+	if err := ensureSupportedVersion(); err != nil {
342
+		return 0, err
343
+	}
344
+
341 345
 	cString := C.CString(name)
342 346
 	defer C.free(unsafe.Pointer(cString))
343 347
 
... ...
@@ -355,6 +385,9 @@ func GetSyscallFromName(name string) (ScmpSyscall, error) {
355 355
 // Returns the number of the syscall, or an error if an invalid architecture is
356 356
 // passed or a syscall with that name was not found.
357 357
 func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
358
+	if err := ensureSupportedVersion(); err != nil {
359
+		return 0, err
360
+	}
358 361
 	if err := sanitizeArch(arch); err != nil {
359 362
 		return 0, err
360 363
 	}
... ...
@@ -386,6 +419,10 @@ func GetSyscallFromNameByArch(name string, arch ScmpArch) (ScmpSyscall, error) {
386 386
 func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCondition, error) {
387 387
 	var condStruct ScmpCondition
388 388
 
389
+	if err := ensureSupportedVersion(); err != nil {
390
+		return condStruct, err
391
+	}
392
+
389 393
 	if comparison == CompareInvalid {
390 394
 		return condStruct, fmt.Errorf("invalid comparison operator")
391 395
 	} else if arg > 5 {
... ...
@@ -413,6 +450,10 @@ func MakeCondition(arg uint, comparison ScmpCompareOp, values ...uint64) (ScmpCo
413 413
 // GetNativeArch returns architecture token representing the native kernel
414 414
 // architecture
415 415
 func GetNativeArch() (ScmpArch, error) {
416
+	if err := ensureSupportedVersion(); err != nil {
417
+		return ArchInvalid, err
418
+	}
419
+
416 420
 	arch := C.seccomp_arch_native()
417 421
 
418 422
 	return archFromNative(arch)
... ...
@@ -435,6 +476,10 @@ type ScmpFilter struct {
435 435
 // Returns a reference to a valid filter context, or nil and an error if the
436 436
 // filter context could not be created or an invalid default action was given.
437 437
 func NewFilter(defaultAction ScmpAction) (*ScmpFilter, error) {
438
+	if err := ensureSupportedVersion(); err != nil {
439
+		return nil, err
440
+	}
441
+
438 442
 	if err := sanitizeAction(defaultAction); err != nil {
439 443
 		return nil, err
440 444
 	}
... ...
@@ -7,7 +7,6 @@ package seccomp
7 7
 
8 8
 import (
9 9
 	"fmt"
10
-	"os"
11 10
 	"syscall"
12 11
 )
13 12
 
... ...
@@ -192,12 +191,12 @@ func checkVersionAbove(major, minor, micro int) bool {
192 192
 		(verMajor == major && verMinor == minor && verMicro >= micro)
193 193
 }
194 194
 
195
-// Init function: Verify library version is appropriate
196
-func init() {
195
+// Ensure that the library is supported, i.e. >= 2.1.0.
196
+func ensureSupportedVersion() error {
197 197
 	if !checkVersionAbove(2, 1, 0) {
198
-		fmt.Fprintf(os.Stderr, "Libseccomp version too low: minimum supported is 2.1.0, detected %d.%d.%d", C.C_VERSION_MAJOR, C.C_VERSION_MINOR, C.C_VERSION_MICRO)
199
-		os.Exit(-1)
198
+		return VersionError{}
200 199
 	}
200
+	return nil
201 201
 }
202 202
 
203 203
 // Filter helpers
... ...
@@ -217,7 +216,10 @@ func (f *ScmpFilter) getFilterAttr(attr scmpFilterAttr) (C.uint32_t, error) {
217 217
 	}
218 218
 
219 219
 	if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
220
-		return 0x0, fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
220
+		return 0x0, VersionError{
221
+			message: "thread synchronization attribute is not supported",
222
+			minimum: "2.2.0",
223
+		}
221 224
 	}
222 225
 
223 226
 	var attribute C.uint32_t
... ...
@@ -240,7 +242,10 @@ func (f *ScmpFilter) setFilterAttr(attr scmpFilterAttr, value C.uint32_t) error
240 240
 	}
241 241
 
242 242
 	if !checkVersionAbove(2, 2, 0) && attr == filterAttrTsync {
243
-		return fmt.Errorf("the thread synchronization attribute is not supported in this version of the library")
243
+		return VersionError{
244
+			message: "thread synchronization attribute is not supported",
245
+			minimum: "2.2.0",
246
+		}
244 247
 	}
245 248
 
246 249
 	retCode := C.seccomp_attr_set(f.filterCtx, attr.toNative(), value)
... ...
@@ -296,7 +301,10 @@ func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact b
296 296
 	} else {
297 297
 		// We don't support conditional filtering in library version v2.1
298 298
 		if !checkVersionAbove(2, 2, 1) {
299
-			return fmt.Errorf("conditional filtering requires libseccomp version >= 2.2.1")
299
+			return VersionError{
300
+				message: "conditional filtering is not supported",
301
+				minimum: "2.2.1",
302
+			}
300 303
 		}
301 304
 
302 305
 		for _, cond := range conds {