Browse code

Apply apparmor before restrictions

There is not need for the remount hack, we use aa_change_onexec so the
apparmor profile is not applied until we exec the users app.
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)

Michael Crosby authored on 2014/05/02 11:09:12
Showing 5 changed files
... ...
@@ -20,7 +20,7 @@ func IsEnabled() bool {
20 20
 	return false
21 21
 }
22 22
 
23
-func ApplyProfile(pid int, name string) error {
23
+func ApplyProfile(name string) error {
24 24
 	if name == "" {
25 25
 		return nil
26 26
 	}
... ...
@@ -2,12 +2,10 @@
2 2
 
3 3
 package apparmor
4 4
 
5
-import ()
6
-
7 5
 func IsEnabled() bool {
8 6
 	return false
9 7
 }
10 8
 
11
-func ApplyProfile(pid int, name string) error {
9
+func ApplyProfile(name string) error {
12 10
 	return nil
13 11
 }
... ...
@@ -4,11 +4,12 @@ package console
4 4
 
5 5
 import (
6 6
 	"fmt"
7
-	"github.com/dotcloud/docker/pkg/label"
8
-	"github.com/dotcloud/docker/pkg/system"
9 7
 	"os"
10 8
 	"path/filepath"
11 9
 	"syscall"
10
+
11
+	"github.com/dotcloud/docker/pkg/label"
12
+	"github.com/dotcloud/docker/pkg/system"
12 13
 )
13 14
 
14 15
 // Setup initializes the proper /dev/console inside the rootfs path
... ...
@@ -72,18 +72,17 @@ func Init(container *libcontainer.Container, uncleanRootfs, consolePath string,
72 72
 
73 73
 	runtime.LockOSThread()
74 74
 
75
+	if err := apparmor.ApplyProfile(container.Context["apparmor_profile"]); err != nil {
76
+		return fmt.Errorf("set apparmor profile %s: %s", container.Context["apparmor_profile"], err)
77
+	}
78
+	if err := label.SetProcessLabel(container.Context["process_label"]); err != nil {
79
+		return fmt.Errorf("set process label %s", err)
80
+	}
75 81
 	if container.Context["restrictions"] != "" {
76 82
 		if err := restrict.Restrict(); err != nil {
77 83
 			return err
78 84
 		}
79 85
 	}
80
-
81
-	if err := apparmor.ApplyProfile(os.Getpid(), container.Context["apparmor_profile"]); err != nil {
82
-		return err
83
-	}
84
-	if err := label.SetProcessLabel(container.Context["process_label"]); err != nil {
85
-		return fmt.Errorf("set process label %s", err)
86
-	}
87 86
 	if err := FinalizeNamespace(container); err != nil {
88 87
 		return fmt.Errorf("finalize namespace %s", err)
89 88
 	}
... ...
@@ -4,8 +4,6 @@ package restrict
4 4
 
5 5
 import (
6 6
 	"fmt"
7
-	"os"
8
-	"path/filepath"
9 7
 	"syscall"
10 8
 
11 9
 	"github.com/dotcloud/docker/pkg/system"
... ...
@@ -23,26 +21,5 @@ func Restrict() error {
23 23
 	if err := system.Mount("/dev/null", "/proc/kcore", "", syscall.MS_BIND, ""); err != nil {
24 24
 		return fmt.Errorf("unable to bind-mount /dev/null over /proc/kcore")
25 25
 	}
26
-
27
-	// This weird trick will allow us to mount /proc read-only, while being able to use AppArmor.
28
-	// This is because apparently, loading an AppArmor profile requires write access to /proc/1/attr.
29
-	// So we do another mount of procfs, ensure it's write-able, and bind-mount a subset of it.
30
-	if err := os.Mkdir(".proc", 0700); err != nil {
31
-		return fmt.Errorf("unable to create temporary proc mountpoint .proc: %s", err)
32
-	}
33
-	if err := system.Mount("proc", ".proc", "proc", 0, ""); err != nil {
34
-		return fmt.Errorf("unable to mount proc on temporary proc mountpoint: %s", err)
35
-	}
36
-	if err := system.Mount("proc", ".proc", "", syscall.MS_REMOUNT, ""); err != nil {
37
-		return fmt.Errorf("unable to remount proc read-write: %s", err)
38
-	}
39
-	for _, path := range []string{"attr", "task"} {
40
-		if err := system.Mount(filepath.Join(".proc", "1", path), filepath.Join("proc", "1", path), "", syscall.MS_BIND, ""); err != nil {
41
-			return fmt.Errorf("unable to bind-mount %s: %s", path, err)
42
-		}
43
-	}
44
-	if err := system.Unmount(".proc", 0); err != nil {
45
-		return fmt.Errorf("unable to unmount temporary proc filesystem: %s", err)
46
-	}
47
-	return os.RemoveAll(".proc")
26
+	return nil
48 27
 }