Skip to content

Commit 11a9983

Browse files
committed
libct/specconv: fix partial clear of atime mount flags
When parsing mount options into recAttrSet and recAttrClr, the code sets attr_clr to individual atime flags (e.g. MOUNT_ATTR_NOATIME or MOUNT_ATTR_STRICTATIME) when clearing atime attributes. However, this violates the kernel's requirement documented in mount_setattr(2)[1]: > Note that, since the access-time values are an enumeration > rather than bit values, a caller wanting to transition to a > different access-time setting cannot simply specify the > access-time setting in attr_set, but must also include > MOUNT_ATTR__ATIME in the attr_clr field. The kernel will > verify that MOUNT_ATTR__ATIME isn't partially set in > attr_clr (i.e., either all bits in the MOUNT_ATTR__ATIME > bit field are either set or clear), and that attr_set > doesn't have any access-time bits set if MOUNT_ATTR__ATIME > isn't set in attr_clr. Passing only a single atime flag (e.g. MOUNT_ATTR_RELATIME) in attr_clr causes mount_setattr() to fail with EINVAL. This change ensures that whenever an atime mode is updated, attr_clr includes MOUNT_ATTR__ATIME to properly reset the entire access-time attribute field before applying the new mode. [1] https://man7.org/linux/man-pages/man2/mount_setattr.2.html Signed-off-by: lifubang <[email protected]> (cherry picked from commit 5560d55) Signed-off-by: lifubang <[email protected]>
1 parent e430416 commit 11a9983

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

libcontainer/specconv/spec_linux.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,11 +1164,11 @@ func parseMountOptions(options []string) *configs.Mount {
11641164
} else {
11651165
recAttrSet |= f.flag
11661166
recAttrClr &= ^f.flag
1167-
if f.flag&unix.MOUNT_ATTR__ATIME == f.flag {
1168-
// https://man7.org/linux/man-pages/man2/mount_setattr.2.html
1169-
// "cannot simply specify the access-time setting in attr_set, but must also include MOUNT_ATTR__ATIME in the attr_clr field."
1170-
recAttrClr |= unix.MOUNT_ATTR__ATIME
1171-
}
1167+
}
1168+
if f.flag&unix.MOUNT_ATTR__ATIME == f.flag {
1169+
// https://man7.org/linux/man-pages/man2/mount_setattr.2.html
1170+
// "cannot simply specify the access-time setting in attr_set, but must also include MOUNT_ATTR__ATIME in the attr_clr field."
1171+
recAttrClr |= unix.MOUNT_ATTR__ATIME
11721172
}
11731173
} else if f, exists := extensionFlags[o]; exists {
11741174
if f.clear {

tests/integration/mounts_recursive.bats

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function teardown_volume() {
2323

2424
function setup() {
2525
setup_volume
26-
setup_busybox
26+
setup_debian
2727
}
2828

2929
function teardown() {
@@ -76,3 +76,53 @@ function teardown() {
7676
[ "$status" -eq 1 ]
7777
[[ "${output}" == *"Read-only file system"* ]]
7878
}
79+
80+
# https://github.com/opencontainers/runc/issues/5095
81+
@test "runc run [ check rbind,r*atime mounts]" {
82+
requires_kernel 5.12
83+
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt1\", options: [\"rbind\",\"ratime\"]}]"
84+
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt2\", options: [\"rbind\",\"rnoatime\"]}]"
85+
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt3\", options: [\"rbind\",\"rstrictatime\"]}]"
86+
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt4\", options: [\"rbind\",\"rnostrictatime\"]}]"
87+
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt5\", options: [\"rbind\",\"rrelatime\"]}]"
88+
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt6\", options: [\"rbind\",\"rnorelatime\"]}]"
89+
90+
runc run -d --console-socket "$CONSOLE_SOCKET" test_rbind_ratime
91+
[ "$status" -eq 0 ]
92+
93+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt1
94+
[[ "${output}" == "rw,relatime,"* ]]
95+
96+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt1/subvol
97+
[[ "${output}" == "rw,relatime,"* ]]
98+
99+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt2
100+
[[ "${output}" == "rw,noatime,"* ]]
101+
102+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt2/subvol
103+
[[ "${output}" == "rw,noatime,"* ]]
104+
105+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt3
106+
[[ "${output}" == "rw,"* ]]
107+
108+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt3/subvol
109+
[[ "${output}" == "rw,"* ]]
110+
111+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt4
112+
[[ "${output}" == "rw,relatime,"* ]]
113+
114+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt4/subvol
115+
[[ "${output}" == "rw,relatime,"* ]]
116+
117+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt5
118+
[[ "${output}" == "rw,relatime,"* ]]
119+
120+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt5/subvol
121+
[[ "${output}" == "rw,relatime,"* ]]
122+
123+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt6
124+
[[ "${output}" == "rw,relatime,"* ]]
125+
126+
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt6/subvol
127+
[[ "${output}" == "rw,relatime,"* ]]
128+
}

0 commit comments

Comments
 (0)