A flaw was identified in the copy-up logic within copyup.rs. When a directory originating from a lower layer with restrictive permissions (e.g., 0700) undergoes a copy-up operation (for example, when a file is created inside it or an attribute is changed), its permissions are permanently widened in the upper layer without being restored to their original state.
This introduces a confidentiality vulnerability/information disclosure regression. In multi-tenant environments or rootless container scenarios (e.g., Podman/Buildah sharing an upperdir), other local users or containers can list and traverse directories that were intended to be private.
Technical Analysis
In create_node_directory(), the temporary directory is created by widening the original mode with 0o755 to ensure it remains writable during the setup of extended attributes (xattrs) and timestamps:
fs::mkdirat(workdir_fd, &c_wd_name, st.st_mode | 0o755)?;
However, unlike the regular file path further down in copyup(), there is no subsequent fchmod call to restore the original mode before the directory is renamed to its final destination.
For regular files, the pattern correctly widens, writes, and restores:
let dfd = openat2::safe_openat(
workdir_fd, wd_name.as_bytes(),
libc::O_CREAT | libc::O_WRONLY,
mode | 0o200, // temporarily widen
)?;
...
// Restore original mode
let _ = crate::sys::fs::fchmod(dfd.as_raw_fd(), mode); // <-- Restores here
For directories, it follows a widen -> write -> rename pattern, completely omitting the restoration step. This causes a 0600 or 0700 directory to permanently become 0755 (or worse, st.st_mode | 0o755) in the upper layer.
Impact
- Vulnerability Type: Information Disclosure / Permissions Bypass
- Severity: Medium/High (depending on the environment deployment, especially critical in rootless container environments sharing underlying storage layers).
- Exploitability: Trivial. Any standard modification inside a restricted lower-layer directory triggers the copy-up and flattens the security bounds.
Suggested Fix
Mirror the file path logic by explicitly restoring the original mode via fchmod right before the directory is renamed:
let _ = fs::fchmod(dfd.as_raw_fd(), st.st_mode & 0o7777);
A flaw was identified in the
copy-uplogic withincopyup.rs. When a directory originating from a lower layer with restrictive permissions (e.g.,0700) undergoes a copy-up operation (for example, when a file is created inside it or an attribute is changed), its permissions are permanently widened in the upper layer without being restored to their original state.This introduces a confidentiality vulnerability/information disclosure regression. In multi-tenant environments or rootless container scenarios (e.g., Podman/Buildah sharing an
upperdir), other local users or containers can list and traverse directories that were intended to be private.Technical Analysis
In
create_node_directory(), the temporary directory is created by widening the original mode with0o755to ensure it remains writable during the setup of extended attributes (xattrs) and timestamps:However, unlike the regular file path further down in
copyup(), there is no subsequentfchmodcall to restore the original mode before the directory is renamed to its final destination.For regular files, the pattern correctly widens, writes, and restores:
For directories, it follows a
widen -> write -> renamepattern, completely omitting the restoration step. This causes a0600or0700directory to permanently become0755(or worse,st.st_mode | 0o755) in the upper layer.Impact
Suggested Fix
Mirror the file path logic by explicitly restoring the original mode via
fchmodright before the directory is renamed: