Browse code

docker: Fix apparmor not being applied to exec processes

Change-Id: I22177b7afced8a1fa3e75f73fc4c8ac6477fd8b0
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/5595
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Sharath George

Srivatsa S. Bhat authored on 2018/09/07 03:10:14
Showing 2 changed files
... ...
@@ -4,7 +4,7 @@
4 4
 Summary:        Docker
5 5
 Name:           docker
6 6
 Version:        17.06.0
7
-Release:        6%{?dist}
7
+Release:        7%{?dist}
8 8
 License:        ASL 2.0
9 9
 URL:            http://docs.docker.com
10 10
 Group:          Applications/File
... ...
@@ -28,6 +28,7 @@ Source5:        https://github.com/cpuguy83/go-md2man/tree/go-md2man-a65d4d2.tar
28 28
 Source6:        default-disable.preset
29 29
 Patch0:         remove-firewalld.patch
30 30
 Patch1:         CVE-2017-14992.patch
31
+Patch2:         fix-apparmor-not-being-applied-to-exec-processes.patch
31 32
 
32 33
 BuildRequires:  systemd
33 34
 BuildRequires:  systemd-devel
... ...
@@ -78,6 +79,7 @@ ln -s docker-ce/components/packaging packaging
78 78
 
79 79
 %patch0 -p2
80 80
 %patch1 -p2
81
+%patch2 -p2
81 82
 
82 83
 mkdir -p /go/src/github.com
83 84
 cd /go/src/github.com
... ...
@@ -225,6 +227,8 @@ rm -rf %{buildroot}/*
225 225
 %{_datadir}/vim/vimfiles/syntax/dockerfile.vim
226 226
 
227 227
 %changelog
228
+*   Thu Sep 06 2018 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 17.06.0-7
229
+-   Fix AppArmor not being applied to exec processes.
228 230
 *   Wed Aug 08 2018 Dweep Advani <dadvani@vmware.com> 17.06.0-6
229 231
 -   Patching for CVE-2017-14992
230 232
 *   Wed Jul 25 2018 Keerthana K <keerthanak@vmware.com> 17.06.0-5
231 233
new file mode 100644
... ...
@@ -0,0 +1,121 @@
0
+From 8f3308ae10ec9ad0dd4edfb46fde53a0e1e19b34 Mon Sep 17 00:00:00 2001
1
+From: Sebastiaan van Stijn <github@gone.nl>
2
+Date: Fri, 2 Mar 2018 13:17:56 +0100
3
+Subject: [PATCH] Fix AppArmor not being applied to Exec processes
4
+
5
+Exec processes do not automatically inherit AppArmor
6
+profiles from the container.
7
+
8
+This patch sets the AppArmor profile for the exec
9
+process.
10
+
11
+Before this change:
12
+
13
+    apparmor_parser -q -r <<EOF
14
+    #include <tunables/global>
15
+    profile deny-write flags=(attach_disconnected) {
16
+      #include <abstractions/base>
17
+      file,
18
+      network,
19
+      deny /tmp/** w,
20
+      capability,
21
+    }
22
+    EOF
23
+
24
+    docker run -dit --security-opt "apparmor=deny-write" --name aa busybox
25
+
26
+    docker exec aa sh -c 'mkdir /tmp/test'
27
+    (no error)
28
+
29
+With this change applied:
30
+
31
+    docker exec aa sh -c 'mkdir /tmp/test'
32
+    mkdir: can't create directory '/tmp/test': Permission denied
33
+
34
+Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
35
+---
36
+ daemon/exec_linux.go      |  3 +++
37
+ daemon/exec_linux_test.go | 53 +++++++++++++++++++++++++++++++++++++++
38
+ 2 files changed, 56 insertions(+)
39
+ create mode 100644 daemon/exec_linux_test.go
40
+
41
+diff -Naurp docker-ce-17.06-orig/components/engine/daemon/exec_linux.go docker-ce-17.06-modified/components/engine/daemon/exec_linux.go
42
+--- docker-ce-17.06-orig/components/engine/daemon/exec_linux.go	2017-07-14 20:34:55.000000000 -0700
43
+@@ -29,6 +29,8 @@ func execSetPlatformOpt(c *container.Con
44
+ 		if c.AppArmorProfile != "" {
45
+ 			appArmorProfile = c.AppArmorProfile
46
+ 		} else if c.HostConfig.Privileged {
47
++			// `docker exec --privileged` does not currently disable AppArmor
48
++			// profiles. Privileged configuration of the container is inherited
49
+ 			appArmorProfile = "unconfined"
50
+ 		} else {
51
+ 			appArmorProfile = "docker-default"
52
+@@ -45,6 +47,10 @@ func execSetPlatformOpt(c *container.Con
53
+ 				return err
54
+ 			}
55
+ 		}
56
++
57
++		// Note that libcontainerd.Process.ApparmorProfile is
58
++		// a *pointer* to a string.
59
++		p.ApparmorProfile = &appArmorProfile
60
+ 	}
61
+ 	return nil
62
+ }
63
+diff -Naurp docker-ce-17.06-orig/components/engine/daemon/exec_linux_test.go docker-ce-17.06-modified/components/engine/daemon/exec_linux_test.go
64
+--- docker-ce-17.06-orig/components/engine/daemon/exec_linux_test.go	1969-12-31 16:00:00.000000000 -0800
65
+@@ -0,0 +1,53 @@
66
++// +build linux
67
++
68
++package daemon
69
++
70
++import (
71
++	"testing"
72
++
73
++	containertypes "github.com/docker/docker/api/types/container"
74
++	"github.com/docker/docker/container"
75
++	"github.com/docker/docker/daemon/exec"
76
++	"github.com/gotestyourself/gotestyourself/assert"
77
++	"github.com/opencontainers/runc/libcontainer/apparmor"
78
++	"github.com/opencontainers/runtime-spec/specs-go"
79
++)
80
++
81
++func TestExecSetPlatformOpt(t *testing.T) {
82
++	if !apparmor.IsEnabled() {
83
++		t.Skip("requires AppArmor to be enabled")
84
++	}
85
++	d := &Daemon{}
86
++	c := &container.Container{AppArmorProfile: "my-custom-profile"}
87
++	ec := &exec.Config{}
88
++	p := &specs.Process{}
89
++
90
++	err := d.execSetPlatformOpt(c, ec, p)
91
++	assert.NilError(t, err)
92
++	assert.Equal(t, "my-custom-profile", p.ApparmorProfile)
93
++}
94
++
95
++// TestExecSetPlatformOptPrivileged verifies that `docker exec --privileged`
96
++// does not disable AppArmor profiles. Exec currently inherits the `Privileged`
97
++// configuration of the container. See https://github.com/moby/moby/pull/31773#discussion_r105586900
98
++//
99
++// This behavior may change in future, but test for the behavior to prevent it
100
++// from being changed accidentally.
101
++func TestExecSetPlatformOptPrivileged(t *testing.T) {
102
++	if !apparmor.IsEnabled() {
103
++		t.Skip("requires AppArmor to be enabled")
104
++	}
105
++	d := &Daemon{}
106
++	c := &container.Container{AppArmorProfile: "my-custom-profile"}
107
++	ec := &exec.Config{Privileged: true}
108
++	p := &specs.Process{}
109
++
110
++	err := d.execSetPlatformOpt(c, ec, p)
111
++	assert.NilError(t, err)
112
++	assert.Equal(t, "my-custom-profile", p.ApparmorProfile)
113
++
114
++	c.HostConfig = &containertypes.HostConfig{Privileged: true}
115
++	err = d.execSetPlatformOpt(c, ec, p)
116
++	assert.NilError(t, err)
117
++	assert.Equal(t, "unconfined", p.ApparmorProfile)
118
++}