Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,4 @@ aclocal.m4
/auto-build-save
.deps
/*.exe
*.dSYM/
21 changes: 15 additions & 6 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,16 @@ OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \
usage.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
OBJS3=progress.o pipe.o @MD5_ASM@ @ROLL_SIMD@ @ROLL_ASM@
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt_OBJS= popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o popt/poptint.o
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@

TLS_OBJ = tls.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@

# Programs we must have to run the test cases
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
testrun$(EXEEXT) trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT) \
simdtest$(EXEEXT)

CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test testsuite/xattrs-hlink.test

Expand Down Expand Up @@ -312,20 +313,28 @@ test: check

.PHONY: check
check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT)

.PHONY: check29
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=29
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) --protocol=29

.PHONY: check30
check30: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=30
$(srcdir)/runtests.py --rsync-bin=`pwd`/rsync$(EXEEXT) --protocol=30

wildtest.o: wildtest.c t_stub.o lib/wildmatch.c rsync.h config.h
wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@ $(LIBS)

simdtest$(EXEEXT): simd-checksum-x86_64.cpp $(HEADERS)
@if test x"@ROLL_SIMD@" != x; then \
$(CXX) -I. $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -DTEST_SIMD_CHECKSUM1 \
-o $@ $(srcdir)/simd-checksum-x86_64.cpp @ROLL_ASM@ $(LIBS); \
else \
touch $@; \
fi

testsuite/chown-fake.test:
ln -s chown.test $(srcdir)/testsuite/chown-fake.test

Expand All @@ -341,7 +350,7 @@ testsuite/xattrs-hlink.test:

.PHONY: installcheck
installcheck: $(CHECK_PROGS) $(CHECK_SYMLINKS)
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin="$(bindir)/rsync$(EXEEXT)" srcdir="$(srcdir)" $(srcdir)/runtests.sh
$(srcdir)/runtests.py --rsync-bin="$(bindir)/rsync$(EXEEXT)" --srcdir="$(srcdir)" --tooldir=`pwd`

# TODO: Add 'dist' target; need to know which files will be included

Expand Down
146 changes: 145 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,144 @@
# NEWS for rsync 3.4.2 (28 Apr 2026)

## Changes in this version:

### SECURITY RELATED:

Several security-relevant defects were reported and fixed since 3.4.1.
None were assigned a CVE — rsync's fork-per-connection design scopes
the impact of each of these to the attacker's own connection, which is
equivalent to the client closing the socket itself — but they are
fixed here as a matter of hygiene and to reduce the chances of a
future exploitable combination. Many thanks to the external
researchers who reported these issues.

- Fixed a signed integer overflow in the PROXY protocol v2 header
parser: a negative `len` field could bypass the size check and cause
a stack buffer overflow in `read_buf()`. Reported by John Walker of
ZeroPath.

- Fixed an invalid access to the files array. Reported by Calum
Hutton of Rapid7.

- Reject negative token values in the compressed-stream token
decoder; a negative value could cause callers to misinterpret a
missing data pointer as literal data. Reported by Will Sergeant.

- Fixed the element count passed to the xattr `qsort()` (see
https://www.openwall.com/lists/oss-security/2026/04/16/2).

- Fixed a buffer underflow in `clean_fname()`, and added a regression
test.

- Fixed an uninitialized `mul_one` in the AVX2 get_checksum1 path
(undefined behaviour), and added a SIMD-checksum self-test that
cross-checks SSE2, SSSE3 and AVX2 against the C reference on both
aligned and unaligned buffers.

- Fixed an uninitialized `buf1` on the first call to
`get_checksum2()` in the MD4 path (fixes #673).

- Zero all new memory from internal allocations: `my_alloc()` now uses
`calloc`, and `expand_item_list()` zeros the expanded portion after
`realloc`. This gives more predictable behaviour if stale or
uninitialised memory is ever accidentally read.

### BUG FIXES:

- Call `tzset()` before chroot so that log timestamps continue to
reflect the configured local timezone after the daemon chroots
(glibc needs `/etc/localtime`, which is unreachable post-chroot).

- Use the correct time when writing to the log file.

- Do not clear `DISPLAY` unconditionally.

- Fixed a Y2038 bug in `syscall.c` by replacing the `Int32x32To64`
macro (which truncates its arguments to 32 bits) with a plain
64-bit multiplication.

- Fixed ACL ID mapping for non-root users (closes #618).

- Fixed handling of objects with many xattrs on FreeBSD.

- Fixed `--open-noatime` not taking effect when opening regular
files: `O_NOATIME` is now also passed to `do_open_nofollow()`, which
has been used for regular files since the CVE fix "fixed symlink
race condition in sender".

- Ignore "directory has vanished" errors.

- Fixed the removal of multiple leading slashes.

- Added the missing `--dirs` long option.

- Fixed a segfault if `poptGetContext()` returns NULL (e.g. under
OOM) by not passing NULL to `poptReadDefaultConfig()`. Reported by
Ronnie Sahlberg; found with `malloc-fail-tester`.

- Fixed a build error on ia64 NonStop (which treats missing
prototypes as an error, not a warning).

- Fixed a flaky hardlinks test (fixes #735).

### ENHANCEMENTS:

- Added multi-threaded `zstd` compression, gated by a new
`--compress-threads=N` option, with validation and man-page
coverage.

- Documented the `temp dir` parameter in the rsyncd.conf man page
(fixes #820).

- Improved rendering of interior dashes in long-option names in
`md-convert` (perhaps fixes #686).

### PORTABILITY / BUILD:

- Fixed glibc 2.43 const-preserving overloads of `strtok()`,
`strchr()` etc. by declaring the affected locals with the right
constness. Contributed by Holger Hoffstätte.

- Converted the bundled zlib 1.2.8 from K&R-style function
definitions to ANSI prototypes, so it builds with clang 16+.

- Avoid using `bool` as an identifier; it is a keyword in C23.

- `configure.ac`: check for xattr functions in libc first and only
fall back to `-lattr`, avoiding spurious overlinking when `-lattr`
happens to be installed. Contributed by Eli Schwartz.

- Made the build reproducible by honouring `SOURCE_DATE_EPOCH` for
the manpage date.

- Removed obsolete `popt/findme.c` and `popt/findme.h` that upstream
popt 1.14 folded into `popt.c` (fixes #710). Contributed by Alan
Coopersmith.

### INTERNAL:

- Made many module-global variables `const` so they can live in
`.rodata` and enable additional compiler optimization.

### DEVELOPER RELATED:

- Replaced `runtests.sh` with `runtests.py`, a Python test runner
that supports `--valgrind` (with per-process log files so valgrind
output no longer interferes with output comparisons) and
`-j/--parallel` execution for roughly a 7× speed-up on typical
hardware.

- Added a SIMD checksum self-test and a `clean-fname-underflow`
regression test.

- Various CI fixes for macOS and Cygwin (including adding
`simd-checksum` to the expected-skipped lists on platforms without
SIMD), and tests now run on `ubuntu-latest`.

- removed support for the unmaintained rsync-patches archive

------------------------------------------------------------------------------

# NEWS for rsync 3.4.1 (16 Jan 2025)

Release 3.4.1 is a fix for regressions introduced in 3.4.0
Expand All @@ -19,6 +160,7 @@ Release 3.4.1 is a fix for regressions introduced in 3.4.0
- fix to permissions handling in the developer release script

------------------------------------------------------------------------------

# NEWS for rsync 3.4.0 (15 Jan 2025)

Release 3.4.0 is a security release that fixes a number of important vulnerabilities.
Expand Down Expand Up @@ -73,6 +215,7 @@ to develop and test fixes.
- added FreeBSD and Solaris CI builds

------------------------------------------------------------------------------

# NEWS for rsync 3.3.0 (6 Apr 2024)

## Changes in this version:
Expand Down Expand Up @@ -4837,8 +4980,9 @@ to develop and test fixes.

| RELEASE DATE | VER. | DATE OF COMMIT\* | PROTOCOL |
|--------------|--------|------------------|-------------|
| 28 Apr 2026 | 3.4.2 | | 32 |
| 16 Jan 2025 | 3.4.1 | | 32 |
| 15 Jan 2025 | 3.4.0 | | 32 |
| 15 Jan 2025 | 3.4.0 | 15 Jan 2025 | 32 |
| 06 Apr 2024 | 3.3.0 | | 31 |
| 20 Oct 2022 | 3.2.7 | | 31 |
| 09 Sep 2022 | 3.2.6 | | 31 |
Expand Down
2 changes: 1 addition & 1 deletion access.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static void make_mask(char *mask, int plen, int addrlen)
return;
}

static int match_address(const char *addr, const char *tok)
static int match_address(const char *addr, char *tok)
{
char *p;
struct addrinfo hints, *resa, *rest;
Expand Down
2 changes: 1 addition & 1 deletion acls.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,7 +713,7 @@ static uchar recv_ida_entries(int f, ida_entries *ent)
else
id = recv_group_name(f, id, NULL);
} else if (access & NAME_IS_USER) {
if (inc_recurse && am_root && !numeric_ids)
if (inc_recurse && !numeric_ids)
id = match_uid(id);
} else {
if (inc_recurse && (!am_root || !numeric_ids))
Expand Down
2 changes: 1 addition & 1 deletion batch.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static int *flag_ptr[] = {
NULL
};

static char *flag_name[] = {
static const char *const flag_name[] = {
"--recurse (-r)",
"--owner (-o)",
"--group (-g)",
Expand Down
7 changes: 3 additions & 4 deletions checksum.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void parse_checksum_choice(int final_call)
if (valid_checksums.negotiated_nni)
xfer_sum_nni = file_sum_nni = valid_checksums.negotiated_nni;
else {
char *cp = checksum_choice ? strchr(checksum_choice, ',') : NULL;
const char *cp = checksum_choice ? strchr(checksum_choice, ',') : NULL;
if (cp) {
xfer_sum_nni = parse_csum_name(checksum_choice, cp - checksum_choice);
file_sum_nni = parse_csum_name(cp+1, -1);
Expand Down Expand Up @@ -366,9 +366,8 @@ void get_checksum2(char *buf, int32 len, char *sum)

mdfour_begin(&m);

if (len > len1) {
if (buf1)
free(buf1);
if (len > len1 || !buf1) {
free(buf1);
buf1 = new_array(char, len+4);
len1 = len;
}
Expand Down
2 changes: 1 addition & 1 deletion clientname.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ int read_proxy_protocol_header(int fd)
char sig[PROXY_V2_SIG_SIZE];
char ver_cmd;
char fam;
char len[2];
unsigned char len[2];
union {
struct {
char src_addr[4];
Expand Down
3 changes: 3 additions & 0 deletions clientserver.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,8 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
}

if (use_chroot) {
/* Cache timezone data before chroot makes /etc/localtime inaccessible */
tzset();
if (chroot(module_chdir)) {
rsyserr(FLOG, errno, "chroot(\"%s\") failed", module_chdir);
io_printf(f_out, "@ERROR: chroot failed\n");
Expand Down Expand Up @@ -1301,6 +1303,7 @@ int start_daemon(int f_in, int f_out)
p = lp_daemon_chroot();
if (*p) {
log_init(0); /* Make use we've initialized syslog before chrooting. */
tzset();
if (chroot(p) < 0) {
rsyserr(FLOG, errno, "daemon chroot(\"%s\") failed", p);
return -1;
Expand Down
5 changes: 3 additions & 2 deletions compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ extern int need_messages_from_generator;
extern int delete_mode, delete_before, delete_during, delete_after;
extern int do_compression;
extern int do_compression_level;
extern int do_compression_threads;
extern int saw_stderr_opt;
extern int msgs2stderr;
extern char *shell_cmd;
Expand Down Expand Up @@ -131,7 +132,7 @@ static const char *client_info;
* of that protocol for it to be advertised as available. */
static void check_sub_protocol(void)
{
char *dot;
const char *dot;
int their_protocol, their_sub;
int our_sub = get_subprotocol_version();

Expand Down Expand Up @@ -414,7 +415,7 @@ static const char *getenv_nstr(int ntype)
env_str = ntype == NSTR_COMPRESS ? "zlib" : protocol_version >= 30 ? "md5" : "md4";

if (am_server && env_str) {
char *cp = strchr(env_str, '&');
const char *cp = strchr(env_str, '&');
if (cp)
env_str = cp + 1;
}
Expand Down
Loading
Loading