Commit Graph
270 Commits
Author SHA1 Message Date
Andrew Tridgell e7a454ea9c log: escape control chars written to the log file
logit() wrote the message to the log file with a raw fprintf, so an
attacker-controlled filename could inject terminal escapes that an admin later
executes when cat'ing the log (CWE-117).  Route it through filtered_fwrite(),
keeping the trailing newline raw.  Also escape C1 controls (0x80-0x9f, incl CSI)
on filtered_fwrite's use_isprint=0 path, which previously caught only C0.

Reported-by: Leonid Bugaev

The C1 escaping is gated by an escape_c1 flag set only for the log path, so
--8-bit-output / iconv terminal output still passes 8-bit bytes (incl. UTF-8)
through unchanged.

(cherry picked from commit ad64e99590)
2026-07-20 14:51:18 +10:00
Andrew Tridgell f96466c8fb log: don't parse the second '%' of '%%' as a new format escape
log_formatted() renders %% as a literal '%', but log_format_has() still
rescanned the literal '%' as the start of a new escape, so a format such
as --out-format='%%i' misdetected the 'i' and turned on itemizing (and
'%%b'/'%%c'/'%%C' likewise perturbed log_before_transfer and checksum
retention).  Skip the literal so both parsers agree.

Extends the ki58 test: an attribute-only change must not be logged under
--out-format='%%i %n', while a transferred file still renders the
literal '%i'.
2026-07-20 14:19:24 +10:00
Leonid Bugaev 0ac17f5682 Add %% escape to --out-format and --log-file-format strings
The log_formatted() switch had no case for '%', so %% did not
produce a literal percent character.  Add case '%' to output
a single '%' character, matching the printf convention.

Test: testsuite/ki58-log-format-percent_test.py
2026-07-20 14:18:10 +10:00
Andrew Tridgell a74cce06a7 confine operator- and peer-supplied paths to the served module
Route operator-supplied paths (--partial-dir, --backup-dir, alt/copy/link-dest,
--temp-dir, --files-from, --log-file, config and secrets files) and the sender's
own enumeration through the race-safe resolver and an ownership walk that refuses a
target redirected outside the module root.  open_tmpfile() now creates the temp via
the cached held dir fd (do_mkstemp_atfd) so an in-tree dir symlink is followed
safely instead of refused.  Adds --insecure-links to opt back into legacy following;
the daemon hard-refuses the client flag (use the "insecure links" module param).
2026-06-21 18:25:28 +10:00
Andrew Tridgell 578afbb857 log: drop receiver-side assert(!is_utf8) reachable via peer MSG_INFO
A daemon receiver (am_server=1, am_generator=0, send_msgs_to_gen=1) that
receives MSG_INFO/MSG_ERROR/MSG_ERROR_XFER/MSG_WARNING from the wire calls
rwrite() with is_utf8=!am_generator=1 (io.c:read_a_msg).  The
send_msgs_to_gen branch in rwrite() then asserted !is_utf8, giving a
remotely-reachable abort of the per-connection receiver child.

Legitimate senders never put these tags on the wire (they write to their
own terminal), so this never fired on real traffic.  Under NDEBUG the
assert compiles out and the bytes are forwarded raw to the generator,
which logs them with is_utf8=0 through filtered_fwrite -- safe.  Match
that behavior in debug builds: drop the assert and document why is_utf8
may legitimately be set here.

(cherry picked from commit e5a89f3372716ee42fcb145d7a65f9037391e074)
2026-06-15 17:15:28 +10:00
Andrew Tridgell 2626e20777 log: do not dereference F_SUM() for %C on a deleted-entry log line
log_delete() builds a placeholder file_struct with only
(file_extra_cnt + 2) extras — enough for the REQ_EXTRA fields and the
first two OPT_EXTRA slots, but not for the SUM_EXTRA_CNT slots that
F_SUM() reaches into.  When the active out-format / log-format contains
%C and always_checksum is on, log_formatted() called sum_as_hex() on
F_SUM(file) for the placeholder, reading flist_csum_len bytes that begin
before the new_array0() allocation and hex-encoding them into the log
line / FCLIENT message.

A daemon receiver can be driven onto this path entirely from the wire:
the client args line can include --out-format='%o%C' and -c, and
read_a_msg() accepts a multiplexed MSG_DELETED from the peer; a payload
of MAXPATHLEN or more bytes skips the send_msg() forward and lands in
the FCLIENT log_formatted() call with the attacker-supplied format.

A deleted entry has no checksum to print, so fall through to the
existing blank-fill branch when ITEM_DELETED is set.  This also covers
the legitimate generator-side log_delete() callers when the daemon's
configured "log format" contains %C.

(cherry picked from commit 84728d81ef92268fb549c24f393c18a8e8eadfd9)
2026-06-15 17:15:28 +10:00
Andrew Tridgell 6d2be4a328 log: copy forwarded message by length in rwrite(), not strlcpy()
rwrite()'s daemon/logfile branch did strlcpy(msg, buf, MIN(sizeof msg, len+1)),
but strlcpy() scans the whole source with strlen(); buf is the data buffer from
read_a_msg() (io.c) holding exactly len bytes of a forwarded MSG_* payload with
no NUL terminator, so strlen() reads past the message into uninitialised stack.

Copy exactly len (bounded) bytes with memcpy() and NUL-terminate, matching the
(buf, len) contract the rest of rwrite() already honours.  Behaviour is
unchanged for the NUL-terminated callers; the over-read is gone.
2026-06-15 15:24:42 +10:00
Andrew Tridgell c02380f7d3 log/batch: refuse planted symlinks at --log-file and --write/read-batch
- log: open the --log-file / daemon log file through
   safe_open_no_attacker_symlinks() so a planted symlink can't redirect the
   privileged log write;
 - batch: open the --write-batch/--read-batch files the same way (+ an
   S_ISREG check), and restore O_BINARY / an O_CLOEXEC fallback on the batch
   opens.

Tests: log-file-symlink, batch-file-symlink.
2026-06-15 15:24:42 +10:00
Andrew TridgellandClaude Opus 4.7 3d5a5a6568 defence-in-depth: guard cumulative snprintf against length underflow
Two cumulative-snprintf patterns in log.c (rsyserr) and main.c
(output_itemized_counts) had the shape

    len = snprintf(buf, sizeof buf, ...);
    len += snprintf(buf+len, sizeof buf - len, ...);

with no guard between calls. snprintf returns the would-have-been
length on truncation, so a truncated first call leaves
"sizeof buf - len" as a negative-then-promoted-to-size_t value,
underflowing into a huge size_t and writing past buf.

Realistic exposure is small in both cases (log header well under
buffer, only ~5 itemized iterations writing ~25 chars each into a
1024-byte buffer) but the defect class matches bb0a8118 and the
fix is cheap. Guard before each subsequent call.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:20:48 +10:00
Wayne Davison 7e2711bb2b Improve various things in the checksum code
- Size flist checksum data to hold the active size, not the max.
- Add a negotiated hash method to the daemon auth code.
- Use EVP for all openssl digests. This makes it easy to add more
  openssl digest methods and avoids deprecation warnings.
- Support a way to re-enable deprecated digests via openssl conf
  file and allow a default file to be configured.
- Supply a simple openssl-rsync.cnf file to enable legacy digests.
2022-09-10 11:39:37 -07:00
Wayne Davison c3b553a93f Preparing for release of 3.2.4pre2 2022-01-15 17:21:01 -08:00
Wayne Davison 3e44bbd313 Preparing for release of 3.2.4pre1 2022-01-02 15:13:19 -08:00
Wayne Davison b774dbc1c0 Improve --omit-dir-times & --omit-link-times
The code now better handles skipping time setting on dirs and/or links
when --atimes and/or --crtimes is specified without --times.
2021-10-10 13:39:09 -07:00
Wayne Davison 8f1511184a Make gcc die on init overflow of an array.
- Use -pedantic-errors with gcc to make an array-init fatal.
- Fix all the extra warnings that gcc outputs due to this option.
- Also add -Wno-pedantic to gcc if we're using the internal popt
  code (since it has lots of pedantic issues).
2020-09-29 13:18:28 -07:00
Wayne Davison 47351c2b16 Use RSYNC_GITVER in more output 2020-08-03 10:46:31 -07:00
Wayne Davison 592059c8fd Improve error output for local & remote-shell xfers 2020-07-23 11:23:47 -07:00
Wayne Davison 974f49e22a Add --crtimes option. 2020-07-22 12:12:18 -07:00
Wayne Davison f47e5a7732 Mention file & line on OOM and overflow errors.
Also simplify output of src file paths in errors & warnings when
built in a alternate build dir.
2020-07-12 23:25:21 -07:00
Wayne Davison da7a350667 Some number & string improvements
- Use strdup(do_big_num(...)) to replace num_to_byte_string(...).
- Allow a ',' for a decimal point in a SIZE option in some locales.
- Get rid of old (now unused) strdup() compatibility function.
- Try harder to include the newline in a single error message write.
2020-07-11 11:39:36 -07:00
Wayne Davison ff272503b0 Output who_am_i() info in all rsyserr() messages. 2020-06-14 15:54:42 -07:00
Wayne Davison f27a630e46 Don't use c++ comments. 2020-06-13 20:12:15 -07:00
Wayne Davison e63ff70eae Some indentation fixes. 2020-06-13 19:15:02 -07:00
Wayne Davison 916faecb83 Only sender can output non-final stats on error
The receiving side's stats are split between 2 processes until the very end.
2020-06-04 21:40:43 -07:00
Wayne Davison c0268d9217 Some improvements for --msgs2stderr and --daemon.
- Set am_daemon to -1 (from 1) when the daemon is run via rsh.
- Only disable --msgs2stderr for a normal (socket) daemon.
- Forward a -q to the server if --msgs2stderr was also specified.
- Added --no-msgs2stderr option to allow it to be overridden.
2020-05-31 16:02:46 -07:00
Wayne Davison 342921eb97 Merge pull request #5 from benrubson/daemonstats
Have daemon log data sent/received even when exiting with an error.
2020-05-28 13:42:47 -07:00
Wayne Davison d7521f5428 The xxh* checksums don't need to be reversed on output. 2020-05-28 12:33:36 -07:00
benrubson c906619620 Log data sent/received even if error 2020-05-26 19:53:25 +02:00
Wayne Davison 7f2359a5cc Improve some early debug-message newlines.
Avoid a newline issue during the output of --DEBUG=CSUM info from
both the server and the client -- we need to output the full message
with its newline as much as possible.
2020-05-23 21:51:28 -07:00
Wayne Davison f14adfd75e Some var cleanup; move test-util vars into t_stub.c. 2020-04-26 14:54:43 -07:00
Wayne Davison b936741032 Added --atimes and --set-noatime options. 2020-04-23 13:24:15 -07:00
Wayne Davison c5fabfb068 Set Copyright years and make them easier to update
I replaced git-set-file-times with an improved version that I wrote
recently (in python3). A new script uses it to figure out the
last-modified year for each *.[ch] file and updates its copyright.
It also puts the latest year into the latest-year.h file for the
output of --version.
2020-04-09 15:11:37 -07:00
Wayne Davison 8475e0e492 Tweak some indentation. 2020-04-05 17:03:15 -07:00
Wayne Davison c0c6a97c35 Try to fix the iconv crash in bug 11338.
Applying Michal Ruprich's suggested patch for the rwrite() function that
should hopefully help with a bug that I couldn't reproduce.
2019-03-16 11:51:49 -07:00
Wayne Davison 3e2e4b5a33 Tweak the copyright year. 2019-03-16 09:15:49 -07:00
Wayne Davison 473108ae6e Tweak copyright date. 2018-01-14 19:55:07 -08:00
Wayne Davison 416e719bea More archaic-checksum improvements. This makes the len vars clearer
and ensures that only the flist code gets the 2-byte digest len.
2017-11-07 14:01:13 -08:00
Wayne Davison ce854cf021 Add "syslog tag" to rsync daemon config. 2017-04-29 13:49:14 -07:00
Wayne Davison a5a7d3a297 Add --checksum-choice option to choose the checksum algorithms. 2016-05-01 17:06:54 -07:00
Wayne Davison cce44865c1 Fixed logging of %b & %c when using --log-file.
The %b and %c escapes were outputting cumulative values when logged via
--log-file only (the bug didn't affect daemon transfer logging or the
output of the client's --out-format info).  Also unified the %b & %c
switch case to make it easier to maintain.  Fixes bug 11496.
2015-09-07 10:07:17 -07:00
Wayne Davison 453914e35b Update the copyright year. 2015-08-08 12:47:03 -07:00
Wayne Davison dfa5b49110 Bump the year to 2014. 2014-01-26 09:29:15 -08:00
Wayne Davison 32540aa091 Tweak log_delete() to send MSG_DELETED more.
If the client is the sender and it is wanting to log deletes, the
current generator code neglects to send MSG_DELETED to the client side
unless some delete verbosity is enabled.  With this new version on the
generator side, the logfile will now mention deletes, even if the
sending (client) side is an older rsync.  Fixes bug 10182.
2013-11-28 11:13:05 -08:00
Wayne Davison 708db6f772 Git rid of uneeded extern. 2013-10-27 11:26:29 -07:00
Wayne Davison bc0d094d2a Don't use comma_num() in FLOG output. 2013-10-27 09:48:57 -07:00
Wayne Davison a213d1cd6e Move some code from util.c to util2.c and add sum_as_hex(). 2013-06-11 13:36:44 -07:00
Wayne Davison 7e1a9c4d79 Update copyright year. 2013-01-19 11:05:53 -08:00
Wayne Davison 3527677043 Let's cast getpid() to an int instead of a long for snprintf(). 2011-10-08 09:15:36 -07:00
Wayne Davison 69be312b5e Some minor variable and flag cleanup. 2011-01-29 22:01:37 -08:00
Matt McCutchen be8234cd59 Point out that the file_struct in log_delete is zero-initialized
because it is static.

It took me long enough to realize this that I think it is worth
documenting.
2010-04-24 09:51:05 -07:00
Wayne Davison 4351c039ad Mention who got the unknown logcode. 2009-11-08 11:50:43 -08:00