diff --git a/NEWS.md b/NEWS.md
index 4f18bc76..c36b1f6d 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,3 +1,24 @@
+# NEWS for rsync 3.4.1 (16 Jan 2025)
+
+Release 3.4.1 is a fix for regressions introduced in 3.4.0
+
+## Changes in this version:
+
+### BUG FIXES:
+
+ - fixed handling of -H flag with conflict in internal flag values
+
+ - fixed a user after free in logging of failed rename
+
+ - fixed build on systems without openat()
+
+ - removed dependency on alloca() in bundled popt
+
+### DEVELOPER RELATED:
+
+ - 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.
@@ -4816,6 +4837,7 @@ to develop and test fixes.
| RELEASE DATE | VER. | DATE OF COMMIT\* | PROTOCOL |
|--------------|--------|------------------|-------------|
+| 16 Jan 2025 | 3.4.1 | | 32 |
| 15 Jan 2025 | 3.4.0 | | 32 |
| 06 Apr 2024 | 3.3.0 | | 31 |
| 20 Oct 2022 | 3.2.7 | | 31 |
diff --git a/SECURITY.md b/SECURITY.md
index c2435741..f390ff9f 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -9,4 +9,5 @@ help backporting fixes into an older release, feel free to ask.
Email your vulnerability information to rsync's maintainer:
- Wayne Davison
+ Rsync Project
+
diff --git a/generator.c b/generator.c
index 3f13bb95..b56fa569 100644
--- a/generator.c
+++ b/generator.c
@@ -2041,8 +2041,12 @@ int atomic_create(struct file_struct *file, char *fname, const char *slnk, const
if (!skip_atomic) {
if (do_rename(tmpname, fname) < 0) {
+ char *full_tmpname = strdup(full_fname(tmpname));
+ if (full_tmpname == NULL)
+ out_of_memory("atomic_create");
rsyserr(FERROR_XFER, errno, "rename %s -> \"%s\" failed",
- full_fname(tmpname), full_fname(fname));
+ full_tmpname, full_fname(fname));
+ free(full_tmpname);
do_unlink(tmpname);
return 0;
}
diff --git a/packaging/lsb/rsync.spec b/packaging/lsb/rsync.spec
index 294715f7..845b188a 100644
--- a/packaging/lsb/rsync.spec
+++ b/packaging/lsb/rsync.spec
@@ -1,6 +1,6 @@
Summary: A fast, versatile, remote (and local) file-copying tool
Name: rsync
-Version: 3.4.0
+Version: 3.4.1
%define fullversion %{version}
Release: 1
%define srcdir src
@@ -79,9 +79,5 @@ rm -rf $RPM_BUILD_ROOT
%dir /etc/rsync-ssl/certs
%changelog
-* Wed Jan 15 2025 Wayne Davison
-Released 3.4.0.
-
-* Fri Mar 21 2008 Wayne Davison
-Added installation of /etc/xinetd.d/rsync file and some commented-out
-lines that demonstrate how to use the rsync-patches tar file.
+* Thu Jan 16 2025 Rsync Project
+Released 3.4.1.
diff --git a/packaging/samba-rsync b/packaging/samba-rsync
index 8691846a..b291b276 100755
--- a/packaging/samba-rsync
+++ b/packaging/samba-rsync
@@ -121,4 +121,4 @@ fi
cd "$SRC_DIR" || exit 1
echo "Copying files from $SRC_DIR to $RSYNC_SAMBA_HOST ..."
-do_rsync -aivOHP --del -f._$FILT . "$RSYNC_SAMBA_HOST:$DEST_DIR/"
+do_rsync -aivOHP --chown=:rsync --del -f._$FILT . "$RSYNC_SAMBA_HOST:$DEST_DIR/"
diff --git a/popt/findme.c b/popt/findme.c
index ac4cbaed..49fc9f6f 100644
--- a/popt/findme.c
+++ b/popt/findme.c
@@ -25,12 +25,15 @@ const char * findProgramPath(const char * argv0)
if (path == NULL) return NULL;
bufsize = strlen(path) + 1;
- start = pathbuf = alloca(bufsize);
+ start = pathbuf = malloc(bufsize);
if (pathbuf == NULL) return NULL; /* XXX can't happen */
strlcpy(pathbuf, path, bufsize);
bufsize += sizeof "/" - 1 + strlen(argv0);
buf = malloc(bufsize);
- if (buf == NULL) return NULL; /* XXX can't happen */
+ if (buf == NULL) {
+ free(pathbuf);
+ return NULL; /* XXX can't happen */
+ }
chptr = NULL;
/*@-branchstate@*/
@@ -39,8 +42,10 @@ const char * findProgramPath(const char * argv0)
*chptr = '\0';
snprintf(buf, bufsize, "%s/%s", start, argv0);
- if (!access(buf, X_OK))
+ if (!access(buf, X_OK)) {
+ free(pathbuf);
return buf;
+ }
if (chptr)
start = chptr + 1;
@@ -49,6 +54,7 @@ const char * findProgramPath(const char * argv0)
} while (start && *start);
/*@=branchstate@*/
+ free(pathbuf);
free(buf);
return NULL;
diff --git a/rsync.h b/rsync.h
index 9be1297b..479ac484 100644
--- a/rsync.h
+++ b/rsync.h
@@ -84,7 +84,6 @@
#define FLAG_DUPLICATE (1<<4) /* sender */
#define FLAG_MISSING_DIR (1<<4) /* generator */
#define FLAG_HLINKED (1<<5) /* receiver/generator (checked on all types) */
-#define FLAG_GOT_DIR_FLIST (1<<5)/* sender/receiver/generator - dir_flist only */
#define FLAG_HLINK_FIRST (1<<6) /* receiver/generator (w/FLAG_HLINKED) */
#define FLAG_IMPLIED_DIR (1<<6) /* sender/receiver/generator (dirs only) */
#define FLAG_HLINK_LAST (1<<7) /* receiver/generator */
@@ -93,6 +92,7 @@
#define FLAG_SKIP_GROUP (1<<10) /* receiver/generator */
#define FLAG_TIME_FAILED (1<<11)/* generator */
#define FLAG_MOD_NSEC (1<<12) /* sender/receiver/generator */
+#define FLAG_GOT_DIR_FLIST (1<<13)/* sender/receiver/generator - dir_flist only */
/* These flags are passed to functions but not stored. */
diff --git a/syscall.c b/syscall.c
index 8cea2900..34a9bba0 100644
--- a/syscall.c
+++ b/syscall.c
@@ -734,7 +734,7 @@ int secure_relative_open(const char *basedir, const char *relpath, int flags, mo
return -1;
}
-#if !defined(O_NOFOLLOW) || !defined(O_DIRECTORY)
+#if !defined(O_NOFOLLOW) || !defined(O_DIRECTORY) || !defined(AT_FDCWD)
// really old system, all we can do is live with the risks
if (!basedir) {
return open(relpath, flags, mode);
diff --git a/testsuite/hardlinks.test b/testsuite/hardlinks.test
index af2ea408..68fd2701 100644
--- a/testsuite/hardlinks.test
+++ b/testsuite/hardlinks.test
@@ -77,5 +77,11 @@ rm -rf "$todir"
$RSYNC -aHivv --debug=HLINK5 "$name1" "$todir/"
diff $diffopt "$name1" "$todir" || test_fail "solo copy of name1 failed"
+# Make sure there's nothing wrong with sending a single directory with -H
+# enabled (this has broken in 3.4.0 so far, so we need this test).
+rm -rf "$fromdir" "$todir"
+makepath "$fromdir/sym" "$todir"
+checkit "$RSYNC -aH '$fromdir/sym' '$todir'" "$fromdir" "$todir"
+
# The script would have aborted on error, so getting here means we've won.
exit 0
diff --git a/version.h b/version.h
index 60dc938e..e54a4ada 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
-#define RSYNC_VERSION "3.4.0"
+#define RSYNC_VERSION "3.4.1"
#define MAINTAINER_TZ_OFFSET -7.0
diff -upN a/rrsync.1 b/rrsync.1
--- a/rrsync.1
+++ b/rrsync.1
@@ -0,0 +1,176 @@
+.TH "rrsync" "1" "15 Jan 2025" "rrsync from rsync 3.4.1" "User Commands"
+.\" prefix=/usr
+.P
+.SH "NAME"
+.P
+rrsync \- a script to setup restricted rsync users via ssh logins
+.P
+.SH "SYNOPSIS"
+.P
+.nf
+rrsync [-ro|-wo] [-munge] [-no-del] [-no-lock] [-no-overwrite] DIR
+.fi
+.P
+The single non-option argument specifies the restricted \fIDIR\fP to use. It can be
+relative to the user's home directory or an absolute path.
+.P
+The online version of this manpage (that includes cross-linking of topics)
+is available at
+.UR https://download.samba.org/pub/rsync/rrsync.1
+.UE .
+.P
+.SH "DESCRIPTION"
+.P
+A user's ssh login can be restricted to only allow the running of an rsync
+transfer in one of two easy ways:
+.P
+.IP o
+forcing the running of the rrsync script
+.IP o
+forcing the running of an rsync daemon-over-ssh command.
+.P
+Both of these setups use a feature of ssh that allows a command to be forced to
+run instead of an interactive shell. However, if the user's home shell is bash,
+please see BASH SECURITY ISSUE for a potential issue.
+.P
+To use the rrsync script, edit the user's \fB~/.ssh/authorized_keys\fP file and add
+a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:
+.RS 4
+.P
+.nf
+command="rrsync DIR"
+command="rrsync -ro DIR"
+command="rrsync -munge -no-del DIR"
+.fi
+.RE
+.P
+Then, ensure that the rrsync script has your desired option restrictions. You
+may want to copy the script to a local bin dir with a unique name if you want
+to have multiple configurations. One or more rrsync options can be specified
+prior to the \fIDIR\fP if you want to further restrict the transfer.
+.P
+To use an rsync daemon setup, edit the user's \fB~/.ssh/authorized_keys\fP file and
+add a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:
+.RS 4
+.P
+.nf
+command="rsync --server --daemon ."
+command="rsync --server --daemon --config=/PATH/TO/rsyncd.conf ."
+.fi
+.RE
+.P
+Then, ensure that the rsyncd.conf file is created with one or more module names
+with the appropriate path and option restrictions. If rsync's
+\fB\-\-config\fP option is omitted, it defaults to \fB~/rsyncd.conf\fP.
+See the \fBrsyncd.conf\fP(5) manpage for details of how to
+configure an rsync daemon.
+.P
+When using rrsync, there can be just one restricted dir per authorized key. A
+daemon setup, on the other hand, allows multiple module names inside the config
+file, each one with its own path setting.
+.P
+The remainder of this manpage is dedicated to using the rrsync script.
+.P
+.SH "OPTIONS"
+.P
+.IP "\fB\-ro\fP"
+Allow only reading from the DIR. Implies \fB\-no-del\fP and
+\fB\-no-lock\fP.
+.IP "\fB\-wo\fP"
+Allow only writing to the DIR.
+.IP "\fB\-munge\fP"
+Enable rsync's \fB\-\-munge-links\fP on the server side.
+.IP "\fB\-no-del\fP"
+Disable rsync's \fB\-\-delete*\fP and \fB\-\-remove*\fP options.
+.IP "\fB\-no-lock\fP"
+Avoid the single-run (per-user) lock check. Useful with \fB\-munge\fP.
+.IP "\fB\-no-overwrite\fP"
+Enforce \fB\-\-ignore-existing\fP on the server. Prevents overwriting existing
+files when the server is the receiver.
+.IP "\fB\-help\fP, \fB\-h\fP"
+Output this help message and exit.
+.P
+.SH "SECURITY RESTRICTIONS"
+.P
+The rrsync script validates the path arguments it is sent to try to restrict
+them to staying within the specified DIR.
+.P
+The rrsync script rejects rsync's \fB\-\-copy-links\fP option (by
+default) so that a copy cannot dereference a symlink within the DIR to get to a
+file outside the DIR.
+.P
+The rrsync script rejects rsync's \fB\-\-protect-args\fP (\fB\-s\fP) option
+because it would allow options to be sent to the server-side that the script
+cannot check. If you want to support \fB\-\-protect-args\fP, use a daemon-over-ssh
+setup.
+.P
+The rrsync script accepts just a subset of rsync's options that the real rsync
+uses when running the server command. A few extra convenience options are also
+included to help it to interact with BackupPC and accept some convenient user
+overrides.
+.P
+The script (or a copy of it) can be manually edited if you want it to customize
+the option handling.
+.P
+.SH "BASH SECURITY ISSUE"
+.P
+If your users have bash set as their home shell, bash may try to be overly
+helpful and ensure that the user's login bashrc files are run prior to
+executing the forced command. This can be a problem if the user can somehow
+update their home bashrc files, perhaps via the restricted copy, a shared home
+directory, or something similar.
+.P
+One simple way to avoid the issue is to switch the user to a simpler shell,
+such as dash. When choosing the new home shell, make sure that you're not
+choosing bash in disguise, as it is unclear if it avoids the security issue.
+.P
+Another potential fix is to ensure that the user's home directory is not a
+shared mount and that they have no means of copying files outside of their
+restricted directories. This may require you to force the enabling of symlink
+munging on the server side.
+.P
+A future version of openssh may have a change to the handling of forced
+commands that allows it to avoid using the user's home shell.
+.P
+.SH "EXAMPLES"
+.P
+The \fB~/.ssh/authorized_keys\fP file might have lines in it like this:
+.RS 4
+.P
+.nf
+command="rrsync client/logs" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzG...
+command="rrsync -ro results" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmk...
+.fi
+.RE
+.P
+.SH "FILES"
+.P
+~/.ssh/authorized_keys
+.P
+.SH "SEE ALSO"
+.P
+\fBrsync\fP(1), \fBrsyncd.conf\fP(5)
+.P
+.SH "VERSION"
+.P
+This manpage is current for version 3.4.1 of rsync.
+.P
+.SH "CREDITS"
+.P
+rsync is distributed under the GNU General Public License. See the file
+COPYING for details.
+.P
+An rsync web site is available at
+.UR https://rsync.samba.org/
+.UE
+and its github
+project is
+.UR https://github.com/RsyncProject/rsync
+.UE .
+.P
+.SH "AUTHOR"
+.P
+The original rrsync perl script was written by Joe Smith. Many people have
+later contributed to it. The python version was created by Wayne Davison.
diff -upN a/rrsync.1.html b/rrsync.1.html
--- a/rrsync.1.html
+++ b/rrsync.1.html
@@ -0,0 +1,169 @@
+
+rrsync(1) manpage
+
+
+
+
+
NAME
+
rrsync - a script to setup restricted rsync users via ssh logins
+
SYNOPSIS
+
rrsync [-ro|-wo] [-munge] [-no-del] [-no-lock] [-no-overwrite] DIR
+
+
The single non-option argument specifies the restricted DIR to use. It can be
+relative to the user's home directory or an absolute path.
A user's ssh login can be restricted to only allow the running of an rsync
+transfer in one of two easy ways:
+
+
forcing the running of the rrsync script
+
forcing the running of an rsync daemon-over-ssh command.
+
+
Both of these setups use a feature of ssh that allows a command to be forced to
+run instead of an interactive shell. However, if the user's home shell is bash,
+please see BASH SECURITY ISSUE for a potential issue.
+
To use the rrsync script, edit the user's ~/.ssh/authorized_keys file and add
+a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:
Then, ensure that the rrsync script has your desired option restrictions. You
+may want to copy the script to a local bin dir with a unique name if you want
+to have multiple configurations. One or more rrsync options can be specified
+prior to the DIR if you want to further restrict the transfer.
+
To use an rsync daemon setup, edit the user's ~/.ssh/authorized_keys file and
+add a prefix like one of the following (followed by a space) in front of each
+ssh-key line that should be restricted:
Then, ensure that the rsyncd.conf file is created with one or more module names
+with the appropriate path and option restrictions. If rsync's
+--config option is omitted, it defaults to ~/rsyncd.conf.
+See the rsyncd.conf(5) manpage for details of how to
+configure an rsync daemon.
+
When using rrsync, there can be just one restricted dir per authorized key. A
+daemon setup, on the other hand, allows multiple module names inside the config
+file, each one with its own path setting.
+
The remainder of this manpage is dedicated to using the rrsync script.
+
OPTIONS
+
+
+
-ro
+
Allow only reading from the DIR. Implies -no-del and
+-no-lock.
Avoid the single-run (per-user) lock check. Useful with -munge.
+
+
+
-no-overwrite
+
Enforce --ignore-existing on the server. Prevents overwriting existing
+files when the server is the receiver.
+
+
+
-help, -h
+
Output this help message and exit.
+
+
+
SECURITY RESTRICTIONS
+
The rrsync script validates the path arguments it is sent to try to restrict
+them to staying within the specified DIR.
+
The rrsync script rejects rsync's --copy-links option (by
+default) so that a copy cannot dereference a symlink within the DIR to get to a
+file outside the DIR.
+
The rrsync script rejects rsync's --protect-args (-s) option
+because it would allow options to be sent to the server-side that the script
+cannot check. If you want to support --protect-args, use a daemon-over-ssh
+setup.
+
The rrsync script accepts just a subset of rsync's options that the real rsync
+uses when running the server command. A few extra convenience options are also
+included to help it to interact with BackupPC and accept some convenient user
+overrides.
+
The script (or a copy of it) can be manually edited if you want it to customize
+the option handling.
+
BASH SECURITY ISSUE
+
If your users have bash set as their home shell, bash may try to be overly
+helpful and ensure that the user's login bashrc files are run prior to
+executing the forced command. This can be a problem if the user can somehow
+update their home bashrc files, perhaps via the restricted copy, a shared home
+directory, or something similar.
+
One simple way to avoid the issue is to switch the user to a simpler shell,
+such as dash. When choosing the new home shell, make sure that you're not
+choosing bash in disguise, as it is unclear if it avoids the security issue.
+
Another potential fix is to ensure that the user's home directory is not a
+shared mount and that they have no means of copying files outside of their
+restricted directories. This may require you to force the enabling of symlink
+munging on the server side.
+
A future version of openssh may have a change to the handling of forced
+commands that allows it to avoid using the user's home shell.
+
EXAMPLES
+
The ~/.ssh/authorized_keys file might have lines in it like this:
The original rrsync perl script was written by Joe Smith. Many people have
+later contributed to it. The python version was created by Wayne Davison.
+
15 Jan 2025
+
diff -upN a/rsync.1 b/rsync.1
--- a/rsync.1
+++ b/rsync.1
@@ -1,4 +1,4 @@
-.TH "rsync" "1" "14 Jan 2025" "rsync 3.4.0" "User Commands"
+.TH "rsync" "1" "15 Jan 2025" "rsync 3.4.1" "User Commands"
.\" prefix=/usr
.P
.SH "NAME"
@@ -5011,7 +5011,7 @@ Please report bugs! See the web site at
.P
.SH "VERSION"
.P
-This manpage is current for version 3.4.0 of rsync.
+This manpage is current for version 3.4.1 of rsync.
.P
.SH "INTERNAL OPTIONS"
.P
diff -upN a/rsync.1.html b/rsync.1.html
--- a/rsync.1.html
+++ b/rsync.1.html
@@ -4479,7 +4479,7 @@ the comments on the https://rsync.samba.org/.
VERSION
-
This manpage is current for version 3.4.0 of rsync.
+
This manpage is current for version 3.4.1 of rsync.
INTERNAL OPTIONS
The options --server and --sender are used internally by rsync, and should
never be typed by a user under normal circumstances. Some awareness of these
@@ -4509,5 +4509,5 @@ David Bell. I've probably missed some p
people from around the world have helped to maintain and improve it.