@@ -15,13 +15,14 @@ const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NOD
15
15
16
16
func mountReadonly (path string ) error {
17
17
for i := 0 ; i < 5 ; i ++ {
18
- if err := system .Mount ("" , path , "" , syscall .MS_REMOUNT | syscall .MS_RDONLY , "" ); err != nil {
18
+ if err := system .Mount ("" , path , "" , syscall .MS_REMOUNT | syscall .MS_RDONLY , "" ); err != nil && ! os . IsNotExist ( err ) {
19
19
switch err {
20
20
case syscall .EINVAL :
21
21
// Probably not a mountpoint, use bind-mount
22
22
if err := system .Mount (path , path , "" , syscall .MS_BIND , "" ); err != nil {
23
23
return err
24
24
}
25
+
25
26
return system .Mount (path , path , "" , syscall .MS_BIND | syscall .MS_REMOUNT | syscall .MS_RDONLY | syscall .MS_REC | defaultMountFlags , "" )
26
27
case syscall .EBUSY :
27
28
time .Sleep (100 * time .Millisecond )
@@ -30,15 +31,16 @@ func mountReadonly(path string) error {
30
31
return err
31
32
}
32
33
}
34
+
33
35
return nil
34
36
}
37
+
35
38
return fmt .Errorf ("unable to mount %s as readonly max retries reached" , path )
36
39
}
37
40
38
41
// This has to be called while the container still has CAP_SYS_ADMIN (to be able to perform mounts).
39
42
// However, afterwards, CAP_SYS_ADMIN should be dropped (otherwise the user will be able to revert those changes).
40
43
func Restrict (mounts ... string ) error {
41
- // remount proc and sys as readonly
42
44
for _ , dest := range mounts {
43
45
if err := mountReadonly (dest ); err != nil {
44
46
return fmt .Errorf ("unable to remount %s readonly: %s" , dest , err )
@@ -48,5 +50,6 @@ func Restrict(mounts ...string) error {
48
50
if err := system .Mount ("/dev/null" , "/proc/kcore" , "" , syscall .MS_BIND , "" ); err != nil && ! os .IsNotExist (err ) {
49
51
return fmt .Errorf ("unable to bind-mount /dev/null over /proc/kcore: %s" , err )
50
52
}
53
+
51
54
return nil
52
55
}
0 commit comments