@@ -11,67 +11,42 @@ import (
11
11
"github.com/dotcloud/docker/pkg/system"
12
12
)
13
13
14
- // "restrictions" are container paths (files, directories, whatever) that have to be masked.
15
- // maskPath is a "safe" path to be mounted over maskedPath. It can take two special values:
16
- // - if it is "", then nothing is mounted;
17
- // - if it is "EMPTY", then an empty directory is mounted instead.
18
- // If remountRO is true then the maskedPath is remounted read-only (regardless of whether a maskPath was used).
19
- type restriction struct {
20
- maskedPath string
21
- maskPath string
22
- remountRO bool
23
- }
24
-
25
- var restrictions = []restriction {
26
- {"/proc" , "" , true },
27
- {"/sys" , "" , true },
28
- {"/proc/kcore" , "/dev/null" , false },
29
- }
30
-
31
14
// This has to be called while the container still has CAP_SYS_ADMIN (to be able to perform mounts).
32
15
// However, afterwards, CAP_SYS_ADMIN should be dropped (otherwise the user will be able to revert those changes).
33
- // "empty" should be the path to an empty directory.
34
- func Restrict (rootfs , empty string ) error {
35
- for _ , restriction := range restrictions {
36
- dest := filepath .Join (rootfs , restriction .maskedPath )
37
- if restriction .maskPath != "" {
38
- var source string
39
- if restriction .maskPath == "EMPTY" {
40
- source = empty
41
- } else {
42
- source = filepath .Join (rootfs , restriction .maskPath )
43
- }
44
- if err := system .Mount (source , dest , "" , syscall .MS_BIND , "" ); err != nil {
45
- return fmt .Errorf ("unable to bind-mount %s over %s: %s" , source , dest , err )
46
- }
47
- }
48
- if restriction .remountRO {
49
- if err := system .Mount ("" , dest , "" , syscall .MS_REMOUNT | syscall .MS_RDONLY , "" ); err != nil {
50
- return fmt .Errorf ("unable to remount %s readonly: %s" , dest , err )
51
- }
16
+ func Restrict () error {
17
+ // remount proc and sys as readonly
18
+ for _ , dest := range []string {"proc" , "sys" } {
19
+ if err := system .Mount ("" , dest , "" , syscall .MS_REMOUNT | syscall .MS_RDONLY , "" ); err != nil {
20
+ return fmt .Errorf ("unable to remount %s readonly: %s" , dest , err )
52
21
}
53
22
}
54
23
24
+ if err := system .Mount ("/proc/kcore" , "/dev/null" , "" , syscall .MS_BIND , "" ); err != nil {
25
+ return fmt .Errorf ("unable to bind-mount /dev/null over /proc/kcore" )
26
+ }
27
+
55
28
// This weird trick will allow us to mount /proc read-only, while being able to use AppArmor.
56
29
// This is because apparently, loading an AppArmor profile requires write access to /proc/1/attr.
57
30
// So we do another mount of procfs, ensure it's write-able, and bind-mount a subset of it.
58
- tmpProcPath := filepath .Join (rootfs , ".proc" )
59
- if err := os .Mkdir (tmpProcPath , 0700 ); err != nil {
60
- return fmt .Errorf ("unable to create temporary proc mountpoint %s: %s" , tmpProcPath , err )
31
+ var (
32
+ rwAttrPath = filepath .Join (".proc" , "1" , "attr" )
33
+ roAttrPath = filepath .Join ("proc" , "1" , "attr" )
34
+ )
35
+
36
+ if err := os .Mkdir (".proc" , 0700 ); err != nil {
37
+ return fmt .Errorf ("unable to create temporary proc mountpoint .proc: %s" , err )
61
38
}
62
- if err := system .Mount ("proc" , tmpProcPath , "proc" , 0 , "" ); err != nil {
39
+ if err := system .Mount ("proc" , ".proc" , "proc" , 0 , "" ); err != nil {
63
40
return fmt .Errorf ("unable to mount proc on temporary proc mountpoint: %s" , err )
64
41
}
65
- if err := system .Mount ("proc" , tmpProcPath , "" , syscall .MS_REMOUNT , "" ); err != nil {
42
+ if err := system .Mount ("proc" , ".proc" , "" , syscall .MS_REMOUNT , "" ); err != nil {
66
43
return fmt .Errorf ("unable to remount proc read-write: %s" , err )
67
44
}
68
- rwAttrPath := filepath .Join (rootfs , ".proc" , "1" , "attr" )
69
- roAttrPath := filepath .Join (rootfs , "proc" , "1" , "attr" )
70
45
if err := system .Mount (rwAttrPath , roAttrPath , "" , syscall .MS_BIND , "" ); err != nil {
71
46
return fmt .Errorf ("unable to bind-mount %s on %s: %s" , rwAttrPath , roAttrPath , err )
72
47
}
73
- if err := system .Unmount (tmpProcPath , 0 ); err != nil {
48
+ if err := system .Unmount (".proc" , 0 ); err != nil {
74
49
return fmt .Errorf ("unable to unmount temporary proc filesystem: %s" , err )
75
50
}
76
- return nil
51
+ return os . RemoveAll ( ".proc" )
77
52
}
0 commit comments