GHSA-mch3-qr4p-chgm
CVE Information
The sender enumerated each source directory with a plain
opendir()on the full accumulated path -- not through the secure resolver -- so the directory enumeration itself was unconfined. (The file-content OPEN is confined separately; the per-entry scan reuses an fd of the already-open directory purely for speed and adds no confinement of its own.) Two escapes followed:
- Non-daemon sender: an unprivileged user races a parent component from a real directory to a symlink->outside between the file-list scan and the recursive
opendir, so a higher-authority sender (a root nightly backup, or a victim copying an attacker's tree) enumerates an out-of-tree directory and copies its entries -- names, metadata and (preserved) symlink targets -- into the destination.- Daemon following mode (
-L/--copy-dirlinks/--copy-unsafe-links): an in-module symlinked directory pointing OUTSIDE the served module made the daemon follow it and enumerate the out-of-module directory, leaking its entry names/metadata/symlink targets to the client (the content open already refused the out-of-module file data).Fix: open the scan directory through
secure_opendir(), which resolves it withsecure_relative_open()(non-daemon: confined beneath the transfer-root cwd) orsecure_relative_open_at()against the module root pinned by identity (daemon:module_dirfd, opened while still privileged), thenfdopendir()s the held fd. A legitimate in-module symlink/..climb that stays inside the module is still followed; an escape is refused. Symlink-following modes for a NON-daemon sender keep the legacyopendir();--insecure-linksrestores it. Platforms withoutfdopendir/dirfdkeep the legacyopendir()(documented resolver-fallback residual, SECURITY.md).Tests: sender-scan-dir-escape, daemon-scan-dir-escape, daemon-subdir-climb-symlink (in-module climb still followed), daemon-scan-cwd-desync (identity anchor vs a cwd-desyncing symlink).
Affected: rsync 3.4.3 and earlier; fixed in 3.5.0. (Precise introduced-in ranges being finalised.)