mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
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 <lifubang@acmcoder.com>
This commit is contained in:
@@ -1164,11 +1164,11 @@ func parseMountOptions(options []string) *configs.Mount {
|
|||||||
} else {
|
} else {
|
||||||
recAttrSet |= f.flag
|
recAttrSet |= f.flag
|
||||||
recAttrClr &= ^f.flag
|
recAttrClr &= ^f.flag
|
||||||
if f.flag&unix.MOUNT_ATTR__ATIME == f.flag {
|
}
|
||||||
// https://man7.org/linux/man-pages/man2/mount_setattr.2.html
|
if f.flag&unix.MOUNT_ATTR__ATIME == f.flag {
|
||||||
// "cannot simply specify the access-time setting in attr_set, but must also include MOUNT_ATTR__ATIME in the attr_clr field."
|
// https://man7.org/linux/man-pages/man2/mount_setattr.2.html
|
||||||
recAttrClr |= unix.MOUNT_ATTR__ATIME
|
// "cannot simply specify the access-time setting in attr_set, but must also include MOUNT_ATTR__ATIME in the attr_clr field."
|
||||||
}
|
recAttrClr |= unix.MOUNT_ATTR__ATIME
|
||||||
}
|
}
|
||||||
} else if f, exists := extensionFlags[o]; exists {
|
} else if f, exists := extensionFlags[o]; exists {
|
||||||
if f.clear {
|
if f.clear {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function teardown_volume() {
|
|||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
setup_volume
|
setup_volume
|
||||||
setup_busybox
|
setup_debian
|
||||||
}
|
}
|
||||||
|
|
||||||
function teardown() {
|
function teardown() {
|
||||||
@@ -76,3 +76,53 @@ function teardown() {
|
|||||||
[ "$status" -eq 1 ]
|
[ "$status" -eq 1 ]
|
||||||
[[ "${output}" == *"Read-only file system"* ]]
|
[[ "${output}" == *"Read-only file system"* ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# https://github.com/opencontainers/runc/issues/5095
|
||||||
|
@test "runc run [ check rbind,r*atime mounts]" {
|
||||||
|
requires_kernel 5.12
|
||||||
|
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt1\", options: [\"rbind\",\"ratime\"]}]"
|
||||||
|
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt2\", options: [\"rbind\",\"rnoatime\"]}]"
|
||||||
|
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt3\", options: [\"rbind\",\"rstrictatime\"]}]"
|
||||||
|
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt4\", options: [\"rbind\",\"rnostrictatime\"]}]"
|
||||||
|
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt5\", options: [\"rbind\",\"rrelatime\"]}]"
|
||||||
|
update_config ".mounts += [{source: \"${TESTVOLUME}\" , destination: \"/mnt6\", options: [\"rbind\",\"rnorelatime\"]}]"
|
||||||
|
|
||||||
|
runc run -d --console-socket "$CONSOLE_SOCKET" test_rbind_ratime
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt1
|
||||||
|
[[ "${output}" == "rw,relatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt1/subvol
|
||||||
|
[[ "${output}" == "rw,relatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt2
|
||||||
|
[[ "${output}" == "rw,noatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt2/subvol
|
||||||
|
[[ "${output}" == "rw,noatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt3
|
||||||
|
[[ "${output}" == "rw,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt3/subvol
|
||||||
|
[[ "${output}" == "rw,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt4
|
||||||
|
[[ "${output}" == "rw,relatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt4/subvol
|
||||||
|
[[ "${output}" == "rw,relatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt5
|
||||||
|
[[ "${output}" == "rw,relatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt5/subvol
|
||||||
|
[[ "${output}" == "rw,relatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt6
|
||||||
|
[[ "${output}" == "rw,relatime,"* ]]
|
||||||
|
|
||||||
|
runc exec test_rbind_ratime findmnt --noheadings -o options /mnt6/subvol
|
||||||
|
[[ "${output}" == "rw,relatime,"* ]]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user