mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-30 01:41:26 -04:00
Add the rest of the path-based syscall wrappers and migrate every
receiver-side caller:
- do_lchown_at, do_rename_at, do_mkdir_at, do_symlink_at,
do_mknod_at, do_link_at, do_unlink_at, do_rmdir_at,
do_utimensat_at, do_stat_at, do_lstat_at
Same shape as do_chmod_at: open each parent under
secure_relative_open(), call the *at() variant against the dirfd,
fall through to the bare path-based syscall in non-daemon /
chrooted / absolute-path / no-parent cases. macOS's
setattrlist-based set_times tier is also routed through the
utimensat_at path on daemon-no-chroot.
Hardenings to secure_relative_open() itself:
- confine basedir resolution under the same kernel mechanism
used for relpath (basedirs from --copy-dest / --link-dest are
sender-controllable in daemon mode)
- reject any '..' component (bare '..', 'foo/..', 'subdir/..')
so the per-component O_NOFOLLOW fallback can't escape
- return the dirfd we built up from the per-component fallback
when the caller passed O_DIRECTORY (otherwise every do_*_at
failed with EINVAL on platforms without RESOLVE_BENEATH)
Adds testsuite/alt-dest-symlink-race.test and
testsuite/secure-relpath-validation.test (with t_secure_relpath
helper) as regression coverage for the new hardenings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
35 lines
1.3 KiB
Bash
Executable File
35 lines
1.3 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Copyright (C) 2026 by Andrew Tridgell
|
|
|
|
# This program is distributable under the terms of the GNU GPL (see
|
|
# COPYING).
|
|
|
|
# Regression test for codex audit Finding 5: secure_relative_open()'s
|
|
# front-door input check rejects "../foo" and "foo/../bar" but
|
|
# misses bare "..", "subdir/..", and other variants whose "/"-split
|
|
# components contain a literal "..". The kernel-enforced
|
|
# RESOLVE_BENEATH (Linux 5.6+) and O_RESOLVE_BENEATH
|
|
# (FreeBSD 13+, macOS 15+) reject these in-kernel; the per-component
|
|
# walk fallback used on NetBSD, OpenBSD, Solaris, Cygwin and pre-5.6
|
|
# Linux does not -- so the validation must happen at the front door.
|
|
#
|
|
# This test invokes the t_secure_relpath helper, which calls
|
|
# secure_relative_open() with each suspect input and verifies the
|
|
# return value is -1 with errno == EINVAL. EINVAL is the marker
|
|
# that the front-door rejected the input, not the kernel; pre-fix
|
|
# the kernel returns -1 with EXDEV (or, on the per-component
|
|
# fallback, may return a valid fd at all -- "escape").
|
|
|
|
. "$suitedir/rsync.fns"
|
|
|
|
testdir="$scratchdir/relpath-test"
|
|
rm -rf "$testdir"
|
|
mkdir -p "$testdir"
|
|
|
|
if ! "$TOOLDIR/t_secure_relpath" "$testdir"; then
|
|
test_fail "t_secure_relpath rejected one or more inputs incorrectly (see stderr above for the specific case)"
|
|
fi
|
|
|
|
exit 0
|