Skip to content

Commit a3320d4

Browse files
committed
Add OverlayedReadOnly mount type
1 parent 77d1521 commit a3320d4

File tree

5 files changed

+29
-4
lines changed

5 files changed

+29
-4
lines changed

deps/userns_sandbox.c

+10-2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ enum {
5151
MOUNT_TYPE_READWRITE,
5252
MOUNT_TYPE_READONLY,
5353
MOUNT_TYPE_OVERLAYED,
54+
MOUNT_TYPE_OVERLAYED_READONLY,
5455
};
5556

5657
// Linked list of volume mappings
@@ -177,15 +178,20 @@ static void mount_the_world(const char * root_dir,
177178
// setting the bind-mount to be read-only if requested.
178179
bind_mount(entry->outside_path,
179180
path,
180-
entry->type == MOUNT_TYPE_READONLY || entry->type == MOUNT_TYPE_OVERLAYED);
181+
entry->type == MOUNT_TYPE_READONLY || entry->type == MOUNT_TYPE_OVERLAYED || entry->type == MOUNT_TYPE_OVERLAYED_READONLY);
181182

182183
// If we're dealing with an overlayed mount, create a unique
183184
// name to store the state of this mount within our `persist_dir`.
184-
if (entry->type == MOUNT_TYPE_OVERLAYED) {
185+
if (entry->type == MOUNT_TYPE_OVERLAYED || entry->type == MOUNT_TYPE_OVERLAYED_READONLY) {
185186
char bname[PATH_MAX];
186187
hashed_basename(&bname[0], entry->mount_point);
187188
check(TRUE == mount_overlay(path, path, bname, persist_dir, userxattr));
188189
check(0 == chown(path, uid, gid));
190+
191+
// If this is a "read-only" overlay mount, remount as read-only here.
192+
if (entry->type == MOUNT_TYPE_OVERLAYED_READONLY) {
193+
check(0 == mount("overlay", path, "overlay", MS_REMOUNT|MS_RDONLY, ""));
194+
}
189195
}
190196
entry = entry->prev;
191197
}
@@ -446,6 +452,8 @@ int main(int sandbox_argc, char **sandbox_argv) {
446452
mount_type = MOUNT_TYPE_READONLY;
447453
} else if (strcmp(mount_str, "ov") == 0) {
448454
mount_type = MOUNT_TYPE_OVERLAYED;
455+
} else if (strcmp(mount_str, "rov") == 0) {
456+
mount_type = MOUNT_TYPE_OVERLAYED_READONLY;
449457
} else if (strcmp(mount_str, "rw") == 0) {
450458
mount_type = MOUNT_TYPE_READWRITE;
451459
} else {

src/Docker.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ function build_executor_command(exe::DockerExecutor, config::SandboxConfig, user
186186
local mount_type_str
187187
if mount_info.type == MountType.ReadOnly
188188
mount_type_str = ":ro"
189-
elseif mount_info.type == MountType.Overlayed
189+
elseif mount_info.type (MountType.Overlayed, MountType.OverlayedReadOnly)
190190
continue
191191
elseif mount_info.type == MountType.ReadWrite
192192
mount_type_str = ""

src/SandboxConfig.jl

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const AnyRedirectable = Union{Base.AbstractCmd, Base.TTY, <:IO}
55
ReadWrite
66
ReadOnly
77
Overlayed
8+
OverlayedReadOnly
89
end
910
struct MountInfo
1011
host_path::String

src/UserNamespaces.jl

+2
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ function build_executor_command(exe::UserNamespacesExecutor, config::SandboxConf
161161
mount_type_str = ":rw"
162162
elseif mount_info.type == MountType.Overlayed
163163
mount_type_str = ":ov"
164+
elseif mount_info.type == MountType.OverlayedReadOnly
165+
mount_type_str = ":rov"
164166
else
165167
throw(ArgumentError("Unknown mount type: $(mount_info.type)"))
166168
end

test/Sandbox.jl

+15-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ for executor in all_executors
9999

100100
@testset "writing to mounts" begin
101101
mktempdir() do dir
102-
stdout = IOBuffer()
103102
config = SandboxConfig(
104103
Dict(
105104
"/" => MountInfo(rootfs_dir, MountType.Overlayed),
@@ -114,6 +113,21 @@ for executor in all_executors
114113
end
115114
end
116115

116+
@testset "OverlayedReadOnly" begin
117+
mktempdir() do dir
118+
config = SandboxConfig(
119+
Dict(
120+
"/" => MountInfo(rootfs_dir, MountType.Overlayed),
121+
"/read_only" => MountInfo(dir, MountType.OverlayedReadOnly),
122+
);
123+
)
124+
with_executor(executor) do exe
125+
@test success(exe, config, `/bin/sh -c "[ -d /read_only ]"`)
126+
@test !success(exe, config, `/bin/sh -c "echo aperture > /read_only/error.txt 2>&1"`)
127+
end
128+
end
129+
end
130+
117131
@testset "pipelining" begin
118132
pipe = PipeBuffer()
119133
stdout = IOBuffer()

0 commit comments

Comments
 (0)