sandbox: fix filesystems not being mounted read-only.
* Fix /proc not being mounted read-only. * Fix other read-only directories not actually being mounted read-only. This was because the mount(2) system call ignores mount flags when creating a bind mount. The solution is to bind mount the directory first, then remount it as read-only second. Known bug: submounts still don't get mounted as read-only. That is, if we're mounting /usr as read-only, and /usr has a submount of /usr/local, then /usr/local won't get mounted as read-only.
This commit is contained in:
@@ -223,6 +223,7 @@ class Sandbox
|
|||||||
mount!("tmpfs", "/tmp", fstype: "tmpfs")
|
mount!("tmpfs", "/tmp", fstype: "tmpfs")
|
||||||
|
|
||||||
ro.each do |path|
|
ro.each do |path|
|
||||||
|
# XXX bug: submounts don't get mounted readonly.
|
||||||
bind_mount!(path, File.join("/tmp", path), flags: %i[rdonly nodev nosuid])
|
bind_mount!(path, File.join("/tmp", path), flags: %i[rdonly nodev nosuid])
|
||||||
end
|
end
|
||||||
rw.each do |path|
|
rw.each do |path|
|
||||||
@@ -232,7 +233,7 @@ class Sandbox
|
|||||||
if process
|
if process
|
||||||
bind_mount!("/proc", "/tmp/proc")
|
bind_mount!("/proc", "/tmp/proc")
|
||||||
else
|
else
|
||||||
mount!("proc", "/tmp/proc", fstype: "proc")
|
mount!("proc", "/tmp/proc", fstype: "proc", flags: %i[rdonly])
|
||||||
end
|
end
|
||||||
|
|
||||||
if tmp
|
if tmp
|
||||||
@@ -241,7 +242,7 @@ class Sandbox
|
|||||||
mount!("tmpfs", "/tmp/dev/shm", fstype: "tmpfs")
|
mount!("tmpfs", "/tmp/dev/shm", fstype: "tmpfs")
|
||||||
end
|
end
|
||||||
|
|
||||||
remount!("/tmp", flags: %i[rdonly nodev nosuid])
|
remount!("/tmp", flags: %i[rdonly nodev nosuid noexec noatime])
|
||||||
pivot_root!("/tmp")
|
pivot_root!("/tmp")
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -309,7 +310,8 @@ class Sandbox
|
|||||||
# Bind mount a directory to a new mountpoint. Bind mounting `/usr` to
|
# Bind mount a directory to a new mountpoint. Bind mounting `/usr` to
|
||||||
# `/tmp/usr` means `/tmp/usr` refers to the same directory as `/usr`.
|
# `/tmp/usr` means `/tmp/usr` refers to the same directory as `/usr`.
|
||||||
def bind_mount!(source, target, flags: [])
|
def bind_mount!(source, target, flags: [])
|
||||||
mount!(source, target, flags: [:bind, :rec, :private, *flags])
|
mount!(source, target, flags: [:bind, :rec, :private])
|
||||||
|
remount!(target, flags: [:bind, *flags])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Change the root (`/`) directory to the given directory.
|
# Change the root (`/`) directory to the given directory.
|
||||||
@@ -372,7 +374,9 @@ class Sandbox
|
|||||||
:rdonly, 0,
|
:rdonly, 0,
|
||||||
:nosuid, 1,
|
:nosuid, 1,
|
||||||
:nodev, 2,
|
:nodev, 2,
|
||||||
|
:noexec, 3,
|
||||||
:remount, 5,
|
:remount, 5,
|
||||||
|
:noatime, 10,
|
||||||
:bind, 12,
|
:bind, 12,
|
||||||
:rec, 14,
|
:rec, 14,
|
||||||
:private, 18,
|
:private, 18,
|
||||||
|
|||||||
Reference in New Issue
Block a user