mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-10 07:53:45 -04:00
The CVE fix in commit c35e283 made secure_relative_open() walk every
component of relpath with O_NOFOLLOW. That blocks every symlink in the
path, which is stricter than the threat model required: legitimate
directory symlinks within the destination tree (e.g. when using -K /
--copy-dirlinks) are also rejected, breaking delta transfers with
"failed verification -- update discarded". See issue #715.
On Linux 5.6+, openat2(RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS) gives
us exactly what we want: the kernel rejects any resolution that would
escape the starting directory (via "..", absolute paths, or symlinks
pointing outside dirfd) while still following symlinks that resolve
within it. /proc magic-links are blocked too.
Use openat2 first; fall back to the existing per-component O_NOFOLLOW
walk on ENOSYS (kernel < 5.6). The lexical "../" checks at the head
of the function are kept as defense in depth. The Linux gate is
plain #ifdef __linux__: the runtime ENOSYS fallback covers the only
case that actually matters (header present + old kernel), and any
Linux build environment without linux/openat2.h will fail with a
clear "no such file" error rather than silently disabling the
protection.
Verified manually that openat2(RESOLVE_BENEATH) blocks all four
escape patterns (absolute symlink, ../ symlink, lexical .., absolute
path) while allowing direct and within-tree symlinks. The new
testsuite/symlink-dirlink-basis.test (taken from PR #864 by Samuel
Henrique) exercises the issue #715 regression and passes; full
make check passes 47/47.
Test: testsuite/symlink-dirlink-basis.test (8 scenarios)
Fixes: https://github.com/RsyncProject/rsync/issues/715
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
automatic testsuite for rsync -*- text -*- We're trying to develop some more substantial tests to prevent rsync regressions. Ideally, all code changes or bug reports would come with an appropriate test suite. You can run these tests by typing "make check" in the build directory. The tests will run using the rsync binary in the build directory, so you do not need to do "make install" first. Indeed, you probably should not install rsync before running the tests. If you instead type "make installcheck" then the suite will test the rsync binary from its installed location (e.g. /usr/local/bin/rsync). You can use this to test a distribution build, or perhaps to run a new test suite against an old version of rsync. Note that in accordance with the GNU Standards, installcheck does not look for rsync on the path. If the tests pass, you should see a report to that effect. Some tests require being root or some other precondition, and so will normally not be checked -- look at the test scripts for more information. If the tests fail, you will see rather more output. The scratch directory will remain in the build directory. It would be useful if you could include the log messages when reporting a failure. These tests also run automatically on the build farm, and you can see the results on http://build.samba.org/.