Andrew Tridgell [Thu, 16 Apr 2026 00:50:49 +0000 (10:50 +1000)]
fix signed integer overflow in proxy protocol v2 header parsing
The len field in the proxy v2 header was declared as signed char,
allowing a negative size to bypass the validation check and cause
a stack buffer overflow when passed to read_buf() as size_t.
This bug was reported by John Walker from ZeroPath, many thanks for
the clear report!
With the current code this bug does not represent a security issue as
it only results in the exit of the forked process that is specific to
the attached client, so it is equivalent to the client closing the
socket, so no CVE for this, but it is good to fix it to prevent a
future issue.
Andrew Tridgell [Thu, 16 Apr 2026 03:40:59 +0000 (13:40 +1000)]
zlib: convert K&R function definitions to ANSI style
The bundled zlib 1.2.8 used K&R-style function definitions which are
rejected by clang 16+ as hard errors. Convert all 90 functions across
9 files to ANSI-style prototypes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Andrew Tridgell [Sun, 1 Mar 2026 22:35:09 +0000 (09:35 +1100)]
CI: add simd-checksum to expected-skipped on macOS and Cygwin
The new simd-checksum test is skipped on platforms where SIMD
instructions are unavailable (macOS ARM, Cygwin). Add it to the
RSYNC_EXPECT_SKIPPED lists so CI doesn't fail on the mismatch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Andrew Tridgell [Sat, 28 Feb 2026 21:42:04 +0000 (08:42 +1100)]
fix uninitialized mul_one in AVX2 checksum and add SIMD checksum test
The AVX2 get_checksum1_avx2_64() read mul_one before initializing it,
which is undefined behavior. Replace the cmpeq/abs trick with
_mm256_set1_epi8(1) to match the SSSE3 and SSE2 versions.
Add a TEST_SIMD_CHECKSUM1 test mode that verifies all SIMD paths
(SSE2, SSSE3, AVX2, and the full dispatch chain) produce identical
results to the C reference, across multiple buffer sizes with both
aligned and unaligned buffers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Andrew Tridgell [Tue, 30 Dec 2025 07:49:34 +0000 (18:49 +1100)]
reject negative token values in compressed stream receivers
Validate that token numbers read from compressed streams are
non-negative. A negative token value would cause the return value
of recv_*_token() to become positive, which callers interpret as
literal data length, but no data pointer is set on this code path.
While this only causes the receiver to crash (which is process-isolated
and only affects the attacker's own connection), it's still undefined
behavior.
Andrew Tridgell [Tue, 30 Dec 2025 05:21:41 +0000 (16:21 +1100)]
fix uninitialized buf1 in get_checksum2() MD4 path
The static buf1 pointer was only allocated when len > len1, but on
first call with len == 0, this condition is false (0 > 0), leaving
buf1 NULL when passed to memcpy().
Ronnie Sahlberg [Thu, 30 Jan 2025 03:27:38 +0000 (13:27 +1000)]
options.c: Fix segv if poptGetContext returns NULL
If poptGetContext returns NULL, perhaps due to OOM,
a NULL pointer is passed into poptReadDefaultConfig()
which in turns SEGVs when trying to dereference it.
This was found using https://github.com/sahlberg/malloc-fail-tester.git
$ ./test_malloc_failure.sh rsync -Pav crash crosh
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Silent [Mon, 13 Jan 2025 14:01:06 +0000 (15:01 +0100)]
syscall: fix a Y2038 bug by replacing Int32x32To64 with multiplication
Int32x32To64 macro internally truncates the arguments to int32,
while time_t is 64-bit on most/all modern platforms.
Therefore, usage of this macro creates a Year 2038 bug.
Emily [Tue, 5 Aug 2025 14:55:24 +0000 (15:55 +0100)]
Allow `ls(1)` to fail in test setup
This can happen when the tests are unable to `stat(2)` some files in
`/etc`, `/bin`, or `/`, due to Unix permissions or other sandboxing. We
still guard against serious errors, which use exit code 2.
Eli Schwartz [Tue, 22 Apr 2025 20:17:55 +0000 (16:17 -0400)]
configure.ac: check for xattr support both in libc and in -lattr
In 2015, the attr/xattr.h header was fully removed from upstream attr.
In 2020, rsync started preferring the standard header, if it exists:
https://github.com/RsyncProject/rsync/pull/22
But the fix was incomplete. We still looked for the getxattr function in
-lattr, and used it if -lattr exists. This was the case even if the
system libc was sufficient to provide the needed functions. Result:
overlinking to -lattr, if it happened to be installed for any other
reason.
```
checking whether to support extended attributes... Using Linux xattrs
checking for getxattr in -lattr... yes
```
Instead, use a different autoconf macro that first checks if the
function is available for use without any libraries (e.g. it is in
libc).
Result:
```
checking whether to support extended attributes... Using Linux xattrs
checking for library containing getxattr... none required
```
Signed-off-by: Eli Schwartz <eschwartz@gentoo.org>
The test was added in dc34990, it turns out that it's flaky. It failed
once on the Debian build infra, cf. [1].
The problem is that the command `rsync -aH '$fromdir/sym' '$todir'`
updates the mod time of `$todir`, so there might be a diff between the
output of `rsync_ls_lR $fromdir` and `rsync_ls_lR $todir`, if ever rsync
runs 1 second (or more) after the directories were created.
To clarify: it's easy to make the test fails 100% of the times with this
change:
With the fix proposed here, we don't use `checkit` anymore, instead we
just run the rsync command, then a simple `diff` to compare the two
directories. This is exactly what the other `-H` test just above does.
In case there's some doubts, `diff` fails if `sym` is missing:
```
$ mkdir -p foo/sym bar
$ diff foo bar || echo KO!
Only in foo: sym
KO!
```
I tested that, after this commit, the test still catches the `-H`
regression in rsync 3.4.0.
atime of source files could sometimes be overwritten
even though --open-noatime option was used.
To fix that, optional O_NOATIME flag was added
to do_open_nofollow which is also used to open regular
files since fix:
"fixed symlink race condition in sender"
Previously optional O_NOATIME flag was only in do_open.
Chris Lamb [Tue, 12 Aug 2025 19:23:59 +0000 (20:23 +0100)]
Make the build reproducible
From https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1093201:
Whilst working on the Reproducible Builds effort [0], we noticed that
rsync could not be built reproducibly.
This is because the date in the manual page can vary depending on
whether there is a .git directory and the modification time of version.h
and Mafile, which might get modified when patching via quilt.
A patch is attached that makes this use SOURCE_DATE_EPOCH, which
will always be reliable.
Andrew Tridgell [Tue, 17 Dec 2024 21:59:42 +0000 (08:59 +1100)]
fixed symlink race condition in sender
when we open a file that we don't expect to be a symlink use
O_NOFOLLOW to prevent a race condition where an attacker could change
a file between being a normal file and a symlink
Replace unsafe generic function pointer cast with proper type cast for
qsort() comparison function. This fixes a potential type mismatch
warning without changing the behavior.
Colin Watson [Fri, 29 Mar 2024 01:24:32 +0000 (01:24 +0000)]
Allow basic connectivity check via rrsync
rsbackup (https://github.com/ewxrjk/rsbackup) uses "ssh <host> true" to
check that the host in question is reachable. I like to configure my
backed-up hosts to force the backup system to go via `rrsync`, but I
always have to add a local tweak to allow `SSH_ORIGINAL_COMMAND=true` to
work. I think this would be safe enough to include in rrsync.
Fix warning about conflicting lseek/lseek64 prototypes
Clang rightfully complains about conflicting prototypes, as both lseek() variants
are redefined:
syscall.c:394:10: warning: a function declaration without a prototype is deprecated
in all versions of C and is treated as a zero-parameter prototype in C2x, conflicting
with a previous declaration [-Wdeprecated-non-prototype]
off64_t lseek64();
^
/usr/include/unistd.h:350:18: note: conflicting prototype is here
extern __off64_t lseek64 (int __fd, __off64_t __offset, int __whence)
^
1 warning generated.
The point of the #ifdef is to build for the configured OFF_T; there is
no reason to redefine lseek/lseek64, which should have been found
via configure.
Clang rightfully complains about invoking bomb(..) without a proper prototype:
lib/pool_alloc.c:171:16: warning: passing arguments to a function without a prototype
is deprecated in all versions of C and is not supported in C2x [-Wdeprecated-non-prototype]
(*pool->bomb)(bomb_msg, __FILE__, __LINE__);
^
1 warning generated.
Building with clang-16 complains with:
./simd-checksum-x86_64.cpp:204:25: warning: passing 1-byte aligned argument to
16-byte aligned parameter 1 of '_mm_store_si128' may result in an unaligned pointer
access [-Walign-mismatch]
Since 05278935 (- Call mkdir_defmode() instead of do_mkdir(). - Define
orig_umask in this file, not options.c. - Made orig_umask a mode_t, not an
int., 2006-02-24), the type for the global was changed, and therefore on
systems where sizeof(mode_t) != sizeof(int), writes or reads to them will
overflow to adjacent bytes.
Change the type to the one used everywhere else and avoid this problem.
While at it, silence again a warning that is being triggered by
Apple's clang 15.
Wayne Davison [Wed, 30 Oct 2024 05:55:29 +0000 (22:55 -0700)]
Some checksum buffer fixes.
- Put sum2_array into sum_struct to hold an array of sum2 checksums
that are each xfer_sum_len bytes.
- Remove sum2 buf from sum_buf.
- Add macro sum2_at() to access each sum2 array element.
- Throw an error if a sums header has an s2length larger than
xfer_sum_len.
Wayne Davison [Wed, 10 Apr 2024 19:15:49 +0000 (12:15 -0700)]
Get rid of gensend target & cached git version.
- Change the developer flow to not require updating the git-version repo
that the builds used to download a git-version.h file. The Actions now
do a full repo fetch so that the .h file can be generated via the git
history.
- Get rid of the gensend Makefile target that was used for the above.
- Get rid of the pre-push git hook file that called "Make gensend".
- Change the FreeBSD build to save an artifact with its built binaries.