Skip to content

Commit 02d2e1f

Browse files
authored
Merge pull request #3277 from kolyshkin/1.0-fix-ro-dev
[1.0] Fix failure with read-only /dev in spec
2 parents 1505646 + cbb2367 commit 02d2e1f

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

libcontainer/rootfs_linux.go

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"github.com/opencontainers/runc/libcontainer/devices"
2323
"github.com/opencontainers/runc/libcontainer/userns"
2424
"github.com/opencontainers/runc/libcontainer/utils"
25-
libcontainerUtils "github.com/opencontainers/runc/libcontainer/utils"
2625
"github.com/opencontainers/runtime-spec/specs-go"
2726
"github.com/opencontainers/selinux/go-selinux/label"
2827
"github.com/sirupsen/logrus"
@@ -42,7 +41,7 @@ type mountConfig struct {
4241
// needsSetupDev returns true if /dev needs to be set up.
4342
func needsSetupDev(config *configs.Config) bool {
4443
for _, m := range config.Mounts {
45-
if m.Device == "bind" && libcontainerUtils.CleanPath(m.Destination) == "/dev" {
44+
if m.Device == "bind" && utils.CleanPath(m.Destination) == "/dev" {
4645
return false
4746
}
4847
}
@@ -154,15 +153,16 @@ func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) {
154153
// finalizeRootfs sets anything to ro if necessary. You must call
155154
// prepareRootfs first.
156155
func finalizeRootfs(config *configs.Config) (err error) {
157-
// remount dev as ro if specified
156+
// All tmpfs mounts and /dev were previously mounted as rw
157+
// by mountPropagate. Remount them read-only as requested.
158158
for _, m := range config.Mounts {
159-
if libcontainerUtils.CleanPath(m.Destination) == "/dev" {
160-
if m.Flags&unix.MS_RDONLY == unix.MS_RDONLY {
161-
if err := remountReadonly(m); err != nil {
162-
return newSystemErrorWithCausef(err, "remounting %q as readonly", m.Destination)
163-
}
159+
if m.Flags&unix.MS_RDONLY != unix.MS_RDONLY {
160+
continue
161+
}
162+
if m.Device == "tmpfs" || utils.CleanPath(m.Destination) == "/dev" {
163+
if err := remountReadonly(m); err != nil {
164+
return newSystemErrorWithCausef(err, "remounting %q as readonly", m.Destination)
164165
}
165-
break
166166
}
167167
}
168168

@@ -432,12 +432,6 @@ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
432432
return err
433433
}
434434
}
435-
// Initially mounted rw in mountPropagate, remount to ro if flag set.
436-
if m.Flags&unix.MS_RDONLY != 0 {
437-
if err := remount(m, rootfs); err != nil {
438-
return err
439-
}
440-
}
441435
return nil
442436
case "bind":
443437
if err := prepareBindMount(m, rootfs); err != nil {
@@ -1062,10 +1056,10 @@ func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error {
10621056
flags = m.Flags
10631057
)
10641058
// Delay mounting the filesystem read-only if we need to do further
1065-
// operations on it. We need to set up files in "/dev" and tmpfs mounts may
1066-
// need to be chmod-ed after mounting. The mount will be remounted ro later
1067-
// in finalizeRootfs() if necessary.
1068-
if libcontainerUtils.CleanPath(m.Destination) == "/dev" || m.Device == "tmpfs" {
1059+
// operations on it. We need to set up files in "/dev", and other tmpfs
1060+
// mounts may need to be chmod-ed after mounting. These mounts will be
1061+
// remounted ro later in finalizeRootfs(), if necessary.
1062+
if m.Device == "tmpfs" || utils.CleanPath(m.Destination) == "/dev" {
10691063
flags &= ^unix.MS_RDONLY
10701064
}
10711065

tests/integration/mounts.bats

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ function teardown() {
2323
[[ "${lines[0]}" == *'/tmp/bind/config.json'* ]]
2424
}
2525

26+
# https://github.com/opencontainers/runc/issues/2246
2627
@test "runc run [ro tmpfs mount]" {
2728
update_config ' .mounts += [{
2829
source: "tmpfs",
@@ -37,6 +38,16 @@ function teardown() {
3738
[[ "${lines[0]}" == *'ro,'* ]]
3839
}
3940

41+
# https://github.com/opencontainers/runc/issues/3248
42+
@test "runc run [ro /dev mount]" {
43+
update_config ' .mounts |= map((select(.destination == "/dev") | .options += ["ro"]) // .)
44+
| .process.args |= ["grep", "^tmpfs /dev", "/proc/mounts"]'
45+
46+
runc run test_busybox
47+
[ "$status" -eq 0 ]
48+
[[ "${lines[0]}" == *'ro,'* ]]
49+
}
50+
4051
# https://github.com/opencontainers/runc/issues/2683
4152
@test "runc run [tmpfs mount with absolute symlink]" {
4253
# in container, /conf -> /real/conf

0 commit comments

Comments
 (0)