Browse Source

Add a test that the default seccomp profile allows execution of 32 bit binaries

While testing #24510 I noticed that 32 bit syscalls were incorrectly being
blocked and we did not have a test for this, so adding one.

This is only tested on amd64 as it is the only architecture that
reliably supports 32 bit code execution, others only do sometimes.

There is no 32 bit libc in the buildpack-deps so we cannot build
32 bit C code easily so use the simplest assembly program which
just calls the exit syscall.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
Justin Cormack 9 years ago
parent
commit
93bbc76ee5

+ 2 - 0
contrib/syscall-test/Dockerfile

@@ -7,3 +7,5 @@ WORKDIR /usr/src/
 RUN gcc -g -Wall -static userns.c -o /usr/bin/userns-test \
 	&& gcc -g -Wall -static ns.c -o /usr/bin/ns-test \
 	&& gcc -g -Wall -static acct.c -o /usr/bin/acct-test
+
+RUN [ "$(uname -m)" = "x86_64" ] && gcc -s -m32 -nostdlib exit32.s -o /usr/bin/exit32-test || true

+ 7 - 0
contrib/syscall-test/exit32.s

@@ -0,0 +1,7 @@
+.globl _start
+.text
+_start:
+	xorl	%eax, %eax
+	incl	%eax
+	movb	$0, %bl
+	int	$0x80

+ 3 - 0
hack/make/.ensure-syscall-test

@@ -9,6 +9,9 @@ if [ "$DOCKER_ENGINE_GOOS" = "linux" ]; then
 		gcc -g -Wall -static contrib/syscall-test/userns.c -o "${tmpdir}/userns-test"
 		gcc -g -Wall -static contrib/syscall-test/ns.c -o "${tmpdir}/ns-test"
 		gcc -g -Wall -static contrib/syscall-test/acct.c -o "${tmpdir}/acct-test"
+		if [ "$DOCKER_ENGINE_OSARCH" = "linux/amd64" ]; then
+			gcc -s -m32 -nostdlib contrib/syscall-test/exit32.s -o "${tmpdir}/exit32-test"
+		fi
 
 		dockerfile="${tmpdir}/Dockerfile"
 		cat <<-EOF > "$dockerfile"

+ 11 - 0
integration-cli/docker_cli_run_unix_test.go

@@ -1053,6 +1053,17 @@ func (s *DockerSuite) TestRunSeccompAllowPrivCloneUserns(c *check.C) {
 	}
 }
 
+// TestRunSeccompProfileAllow32Bit checks that 32 bit code can run on x86_64
+// with the default seccomp profile.
+func (s *DockerSuite) TestRunSeccompProfileAllow32Bit(c *check.C) {
+	testRequires(c, SameHostDaemon, seccompEnabled, IsAmd64)
+
+	runCmd := exec.Command(dockerBinary, "run", "syscall-test", "exit32-test", "id")
+	if out, _, err := runCommandWithOutput(runCmd); err != nil {
+		c.Fatalf("expected to be able to run 32 bit code, got %s: %v", out, err)
+	}
+}
+
 // TestRunSeccompAllowSetrlimit checks that 'docker run debian:jessie ulimit -v 1048510' succeeds.
 func (s *DockerSuite) TestRunSeccompAllowSetrlimit(c *check.C) {
 	testRequires(c, SameHostDaemon, seccompEnabled)

+ 4 - 0
integration-cli/requirements.go

@@ -38,6 +38,10 @@ var (
 		func() bool { return !utils.ExperimentalBuild() },
 		"Test requires a non experimental daemon",
 	}
+	IsAmd64 = testRequirement{
+		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") == "amd64" },
+		"Test requires a daemon running on amd64",
+	}
 	NotArm = testRequirement{
 		func() bool { return os.Getenv("DOCKER_ENGINE_GOARCH") != "arm" },
 		"Test requires a daemon not running on ARM",