[packages/rssh] Rel 2. Security fixes from Debian (CVE-2019-1000018, CVE-2019-3463, CVE-2019-3464)
arekm
arekm at pld-linux.org
Thu Oct 15 09:20:39 CEST 2026
commit bb91d73bccbce90ab6745dd634a0eeca23242b1e
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date: Thu Oct 15 09:20:03 2026 +0200
Rel 2. Security fixes from Debian (CVE-2019-1000018, CVE-2019-3463, CVE-2019-3464)
rssh-cflags.patch | 28 +++++++++
rssh-chroot-check.patch | 27 ++++++++
rssh-fail-msg-overflow.patch | 23 +++++++
rssh-mkchroot.patch | 18 ------
rssh-rsync-protocol.patch | 143 ++++++++++++++++++++++++++++++++-----------
rssh-scp-options.patch | 86 ++++++++++++++++++++++++++
rssh-setuid-check.patch | 26 ++++++++
rssh-use-after-free.patch | 18 ++++++
rssh-userbuild.patch | 10 +--
rssh.spec | 26 ++++++--
10 files changed, 341 insertions(+), 64 deletions(-)
---
diff --git a/rssh.spec b/rssh.spec
index 688d2cb..3609318 100644
--- a/rssh.spec
+++ b/rssh.spec
@@ -2,14 +2,19 @@ Summary: A restricted shell for assigning scp- or sftp-only access
Summary(pl.UTF-8): Okrojona powłoka dająca dostęp tylko do scp i/lub sftp
Name: rssh
Version: 2.3.4
-Release: 1
+Release: 2
License: BSD-like
Group: Applications/Shells
-Source0: http://downloads.sourceforge.net/rssh/%{name}-%{version}.tar.gz
+Source0: https://downloads.sourceforge.net/rssh/%{name}-%{version}.tar.gz
# Source0-md5: 5211f5fe206704f813a3cec61f487042
Patch0: %{name}-userbuild.patch
-Patch1: %{name}-mkchroot.patch
+Patch1: %{name}-cflags.patch
Patch2: %{name}-rsync-protocol.patch
+Patch3: %{name}-fail-msg-overflow.patch
+Patch4: %{name}-scp-options.patch
+Patch5: %{name}-chroot-check.patch
+Patch6: %{name}-use-after-free.patch
+Patch7: %{name}-setuid-check.patch
URL: http://www.pizzashack.org/rssh/
BuildRequires: autoconf
BuildRequires: automake
@@ -33,14 +38,23 @@ dostęp na danym koncie tylko do scp i/lub sftp.
%prep
%setup -q
%patch -P0 -p1
-%patch -P1
+%patch -P1 -p1
%patch -P2 -p1
+%patch -P3 -p1
+%patch -P4 -p1
+%patch -P5 -p1
+%patch -P6 -p1
+%patch -P7 -p1
+
+%{__sed} -i -e 's,^sftp_server_path=.*,sftp_server_path="%{_libdir}/openssh/sftp-server",' mkchroot.sh
%build
%{__aclocal}
%{__automake}
%{__autoconf}
+CFLAGS="%{rpmcflags} -std=gnu17"
%configure \
+ --disable-static \
--with-scp=/usr/bin/scp \
--with-sftp-server=/usr/%{_lib}/openssh/sftp-server
@@ -99,8 +113,8 @@ ln -sf %{_bindir}/sftpsh /bin/sftpsh
%doc AUTHORS ChangeLog README CHROOT SECURITY mkchroot.sh
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/rssh.conf
%attr(755,root,root) %{_bindir}/%{name}
-%attr(755,root,root) %{_bindir}/scpsh
-%attr(755,root,root) %{_bindir}/sftpsh
+%{_bindir}/scpsh
+%{_bindir}/sftpsh
%attr(4755,root,root) %{_libexecdir}/rssh_chroot_helper
%{_mandir}/man?/*
# legacy
diff --git a/rssh-cflags.patch b/rssh-cflags.patch
new file mode 100644
index 0000000..e6a3005
--- /dev/null
+++ b/rssh-cflags.patch
@@ -0,0 +1,28 @@
+Custom .c.o rule drops CFLAGS passed to configure; based on Debian
+0002-Honor-CFLAGS-CPPFLAGS-passed-to-configure.patch
+
+diff --git a/Makefile.am b/Makefile.am
+index 82b8b21..468aa1f 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,8 +1,7 @@
+ ## Process this file with automake to produce Makefile.in
+ AUTOMAKE_OPTIONS = nostdinc
+-ourdefs = -DPATH_RSSH_CONFIG=\"@sysconfdir@/rssh.conf\" -DPATH_CHROOT_HELPER=\"@libexecdir@/rssh_chroot_helper\"
+-ourflags = @defcflags@ @static@
+-AM_CFLAGS = $(ourflags)
++AM_CPPFLAGS = -DPATH_RSSH_CONFIG=\"@sysconfdir@/rssh.conf\" -DPATH_CHROOT_HELPER=\"@libexecdir@/rssh_chroot_helper\"
++AM_CFLAGS = @defcflags@ @static@
+ bin_PROGRAMS = rssh
+ libexec_PROGRAMS = rssh_chroot_helper
+ nodist_rssh_SOURCES = main.c pathnames.h config.h
+@@ -15,9 +14,6 @@ man_MANS = rssh.1 rssh.conf.5
+ EXTRA_DIST = $(man_MANS) CHROOT SECURITY LICENSE rssh.spec mkchroot.sh conf_convert.sh
+ base=`echo @PACKAGE_STRING@|tr " " "-"`
+
+-.c.o:
+- $(CC) -c $(DEFS) $(ourdefs) $(AM_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $<
+-
+ rpm: dist
+ rpmbuild -ta --sign $(base).tar.gz
+ cp /users/ddm/tmp/RPM/i386/$(base)-1.i386.rpm .
diff --git a/rssh-chroot-check.patch b/rssh-chroot-check.patch
new file mode 100644
index 0000000..5bf2d72
--- /dev/null
+++ b/rssh-chroot-check.patch
@@ -0,0 +1,27 @@
+From: Russ Allbery <rra at debian.org>
+Date: Mon, 28 Jan 2019 20:15:30 -0800
+Subject: Check command line after chroot
+
+When a command was configured with a chroot, rssh did not check
+the safety of the command line after chroot, allowing various
+vectors of remote code execution inside the chroot environment.
+Perform the same check after chroot as is performed before running
+the command when a chroot is not configured.
+
+diff --git a/rssh_chroot_helper.c b/rssh_chroot_helper.c
+index 7780c11..b751e14 100644
+--- a/rssh_chroot_helper.c
++++ b/rssh_chroot_helper.c
+@@ -218,6 +218,12 @@ int main( int argc, char **argv )
+ ch_fatal_error("build_arg_vector()", argv[2],
+ "bad expansion");
+
++ /* check the command for safety */
++ if ( !check_command_line(argvec, &opts) ){
++ fprintf(stderr, "\n");
++ exit(1);
++ }
++
+ /*
+ * This is the old way to figure out what program to run. Since we're
+ * re-parsing the config file in rssh_chroot helper, we could get rid
diff --git a/rssh-fail-msg-overflow.patch b/rssh-fail-msg-overflow.patch
new file mode 100644
index 0000000..2084d7e
--- /dev/null
+++ b/rssh-fail-msg-overflow.patch
@@ -0,0 +1,23 @@
+From: Russ Allbery <rra at debian.org>
+Date: Sat, 7 Dec 2013 18:32:55 -0800
+Subject: Fix buffer allocation buffer for fail message
+
+The failure log message when the user isn't permitted to run the
+command they're attempting includes a summary of the commands the
+user is allowed to run. The allocation for that string was not
+reserving space for the nul byte at the end of the string, causing
+a one-byte overwrite past the end of the string.
+
+diff --git a/util.c b/util.c
+index f98d2bc..9ea3e9e 100644
+--- a/util.c
++++ b/util.c
+@@ -84,7 +84,7 @@ void fail( int flags, int argc, char **argv )
+ /* create msg indicating what is allowed */
+ if ( !size ) cmd = "This user is locked out.";
+ else {
+- size += 18;
++ size += 18 + 1;
+ if ( !(cmd = (char *)malloc(size)) ){
+ log_msg("fatal error: out of mem allocating log msg");
+ exit(1);
diff --git a/rssh-mkchroot.patch b/rssh-mkchroot.patch
deleted file mode 100644
index 0d304ac..0000000
--- a/rssh-mkchroot.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- mkchroot.sh-orig 2004-07-21 20:47:06.000000000 +0000
-+++ mkchroot.sh 2004-07-21 20:55:15.000000000 +0000
-@@ -96,11 +96,11 @@
- # copy SSH files
-
- scp_path="/usr/bin/scp"
--sftp_server_path="/usr/libexec/openssh/sftp-server"
--rssh_path="/usr/bin/rssh"
--chroot_helper_path="/usr/libexec/rssh_chroot_helper"
-+sftp_server_path="/usr/lib/openssh/sftp-server"
-+rssh_path="/bin/rssh"
-+chroot_helper_path="/usr/lib/rssh_chroot_helper"
-
--for jail_path in `dirname "$jail_dir$scp_path"` `dirname "$jail_dir$sftp_server_path"` `dirname "$jail_dir$chroot_helper_path"`; do
-+for jail_path in `dirname "$jail_dir$scp_path"` `dirname "$jail_dir$sftp_server_path"` `dirname "$jail_dir$chroot_helper_path"` `dirname "$jail_dir$rssh_path"`; do
-
- echo "setting up $jail_path"
-
diff --git a/rssh-rsync-protocol.patch b/rssh-rsync-protocol.patch
index 98096d9..8fba041 100644
--- a/rssh-rsync-protocol.patch
+++ b/rssh-rsync-protocol.patch
@@ -1,23 +1,35 @@
-From: Russ Allbery <rra at stanford.edu>
-Subject: [PATCH] Handle the rsync v3 -e option for protocol information
+From: Russ Allbery <rra at debian.org>
+Date: Sat, 7 Dec 2013 18:32:56 -0800
+Subject: Verify rsync command options
As of rsync 3, rsync reused the -e option to pass protocol information
from the client to the server. We therefore cannot reject all -e
options to rsync, only ones not sent with --server or containing
something other than protocol information as an argument.
-Based on work by Robert Hardy.
+Be stricter about the rsync command line and require --server as the
+first argument, which disables attempts to initiate rsync outbound from
+the server and in turn could trigger running code specified in ssh
+client configuration options.
-Debian Bug#471803
+Also scan the rsync command line for any --rsh, --config, or --daemon
+option and reject it as well. This replaces and improves the upstream
+strategy for rejecting that command-line option, taking advantage of
+the parsing added to check the -e option. --config can be used to run
+commands via "pre-xfer exec" when running as a daemon, plus the client
+should not be able to spawn daemons.
-Signed-off-by: Russ Allbery <rra at stanford.edu>
+Unset the HOME environment variable to prevent popt from loading a
+~/.popt configuration file, which could redefine rsync command-line
+options like --server to instead mean some unsafe option, or even run
+commands directly.
----
- util.c | 32 ++++++++++++++++++++++++++++++--
- 1 files changed, 30 insertions(+), 2 deletions(-)
+Based on work by Robert Hardy and a report by Nick Cleaton.
+
+Debian Bug#471803, CVE-2019-3463, CVE-2019-3464
diff --git a/util.c b/util.c
-index e576755..50a63e2 100644
+index 9ea3e9e..3e8bb87 100644
--- a/util.c
+++ b/util.c
@@ -56,6 +56,7 @@
@@ -28,50 +40,109 @@ index e576755..50a63e2 100644
/* LOCAL INCLUDES */
#include "pathnames.h"
-@@ -187,6 +188,33 @@ bool check_command( char *cl, ShellOptions_t *opts, char *cmd, int cmdflag )
+@@ -197,6 +198,68 @@ bool check_command( char *cl, ShellOptions_t *opts, char *cmd, int cmdflag )
}
- /*
-+ * check_rsync_e() - take the command line passed to rssh and look for a -e
-+ * option. If one is found, make sure --server is provided
-+ * and the option contains only the protocol information.
-+ * Returns 1 if the command line is safe; 0 otherwise.
+
++/*
++ * rsync_okay() - require --server on all rsh command lines, check that -e
++ * contains only protocol information, and reject any --rsh,
++ * --config, or --daemon option. Returns FALSE if the command
++ * line should not be allowed, TRUE if it is okay.
+ */
-+static int check_rsync_e( char *cl )
++static int rsync_okay( char **vec )
+{
-+ int status;
+ regex_t re;
+
+ /*
-+ * This is more complicated than it looks because we don't want to
-+ * trigger on the e in --server, but we do want to catch the common
-+ * case of -ltpre.iL (which contains -e.).
++ * rsync will send -e, followed by either just "." (meaning no special
++ * protocol) or "N.N" (meaning a pre-release protocol version),
++ * followed by some number of alphabetic flags indicating various
++ * supported options. There may be other options between - and the e,
++ * but -e will always be the last option in the string. A typical
++ * option passed by the client is "-ltpre.iL".
++ *
++ * Note that if --server is given, this should never be parsed as a
++ * shell, but we'll tightly verify it anyway, just in case.
++ *
++ * This regex matches the acceptable flags containing -e, so if it
++ * does not match, the command line should be rejected.
+ */
-+ static const char pattern[] = "[ \t\v\f]-([^-][^ ]*)?e[^.0-9]";
++ static const char pattern[]
++ = "^-[a-df-zA-Z]*e[0-9]*\\.[0-9]*[a-zA-Z]*$";
+
-+ if ( strstr(cl, "--server") == NULL ) return 0;
++ /*
++ * Only recognize --server if it's the first option. rsync itself
++ * always passes it that way, and if it's not the first argument, it
++ * could be hidden from the server as an argument to some other
++ * option.
++ */
++ if ( !(vec && vec[0] && vec[1] && strcmp(vec[1], "--server") == 0) )
++ return FALSE;
++
++ /* Check the remaining options for -e or --rsh. */
+ if ( regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0 ){
-+ return 0;
++ return FALSE;
++ }
++ while (vec && *vec){
++ if ( strcmp(*vec, "--rsh") == 0
++ || strcmp(*vec, "--daemon") == 0
++ || strcmp(*vec, "--config") == 0
++ || strncmp(*vec, "--rsh=", strlen("--rsh=")) == 0
++ || strncmp(*vec, "--config=", strlen("--config=")) == 0 ){
++ regfree(&re);
++ return FALSE;
++ }
++ if ( strncmp(*vec, "--", 2) != 0 && opt_exist(*vec, 'e') ){
++ if ( regexec(&re, *vec, 0, NULL, 0) != 0 ){
++ regfree(&re);
++ return FALSE;
++ }
++ }
++ vec++;
+ }
-+ status = regexec(&re, cl, 0, NULL, 0);
+ regfree(&re);
-+ return (status == 0) ? 0 : 1;
++ return TRUE;
+}
+
-+/*
++
+ /*
* check_command_line() - take the command line passed to rssh, and verify
- * that the specified command is one the user is
- * allowed to run. Return the path of the command
-@@ -258,7 +258,11 @@ char *check_command_line( char **cl, ShellOptions_t *opts )
+ * that the specified command is one the user is
+@@ -229,16 +292,27 @@ char *check_command_line( char **cl, ShellOptions_t *opts )
+ }
if ( check_command(*cl, opts, PATH_RSYNC, RSSH_ALLOW_RSYNC) ){
- /* filter -e option */
+- /* filter -e option */
- if ( opt_filter(cl, 'e') ) return NULL;
-+ if ( opt_filter(cl, 'e') && !check_rsync_e(cl) ) {
-+ fprintf(stderr, "\ninsecure -e without --server not allowed.");
-+ log_msg("insecure -e option without --server in rsync command line!");
+- while (cl && *cl){
+- if ( strstr(*cl, "--rsh" ) ){
+- fprintf(stderr, "\ninsecure --rsh= not allowed.");
+- log_msg("insecure --rsh option in rsync command line!");
+- return NULL;
+- }
+- cl++;
++ if ( !rsync_okay(cl) ){
++ fprintf(stderr, "\ninsecure rsync options not allowed.");
++ log_msg("insecure rsync options in rsync command line!");
++ return NULL;
+ }
++
++ /*
++ * rsync is linked with popt, which recognizes a configuration
++ * file ~/.popt that can, among other things, define aliases.
++ * If someone can write to the home directory of the rssh
++ * user, they can upload a ~/.popt file that contains
++ * something like "rsync alias --server --rsh" and then
++ * execute commands they upload. popt does not try to read
++ * its configuration file if HOME is not set, so unset HOME to
++ * disable this behavior.
++ */
++ if ( unsetenv("HOME") < 0 ){
++ log_msg("cannot unsetenv() HOME");
+ return NULL;
+ }
- while (cl && *cl){
- if ( strstr(*cl, "--rsh" ) ){
- fprintf(stderr, "\ninsecure --rsh= not allowed.");
++
+ return PATH_RSYNC;
+ }
+ /* No match, return NULL */
diff --git a/rssh-scp-options.patch b/rssh-scp-options.patch
new file mode 100644
index 0000000..9aed822
--- /dev/null
+++ b/rssh-scp-options.patch
@@ -0,0 +1,86 @@
+From: Russ Allbery <rra at debian.org>
+Date: Thu, 17 Jan 2019 19:21:40 -0800
+Subject: Verify scp command options
+
+ESnet discovered a security vulnerability in the scp backend for
+rssh. Since the arguments to scp on the server side were not
+checked, the client could pass in arbitrary scp command-line flags,
+including setting arbitrary scp options. This allows setting the
+option PKCS11Provider, which loads and executes code from a shared
+module.
+
+Even if the -o flag is blocked, this is still possible via -F to
+load an already-uploaded ssh configuration file, or, if .ssh/config
+is writable, by just uploading that configuration file directly
+first.
+
+Attempt to protect against this attack by checking the command line
+of scp and only allowing the options that are passed to the server
+end of the connection. Require either -f or -t be given, which
+disables scp's attempts to connect to a remote host. Allow these as
+-pf and -pt, which are sent by libssh2.
+
+Debian Bug#919623, CVE-2019-1000018
+
+diff --git a/util.c b/util.c
+index 3e8bb87..86cb063 100644
+--- a/util.c
++++ b/util.c
+@@ -260,6 +260,43 @@ static int rsync_okay( char **vec )
+ }
+
+
++/*
++ * scp_okay() - take the command line and check that it is a hopefully-safe scp
++ * server command line, accepting only very specific options.
++ * Returns FALSE if the command line should not be allowed, TRUE
++ * if it is okay.
++ */
++static int scp_okay( char **vec )
++{
++ int saw_f_or_t = FALSE;
++
++ for ( vec++; vec && *vec; vec++ ){
++ /* Allowed options. */
++ if ( strcmp(*vec, "-v") == 0 ) continue;
++ if ( strcmp(*vec, "-r") == 0 ) continue;
++ if ( strcmp(*vec, "-p") == 0 ) continue;
++ if ( strcmp(*vec, "-d") == 0 ) continue;
++ if ( strcmp(*vec, "-f") == 0 || strcmp(*vec, "-pf") == 0 ){
++ saw_f_or_t = TRUE;
++ continue;
++ }
++ if ( strcmp(*vec, "-t") == 0 || strcmp(*vec, "-pt") == 0 ){
++ saw_f_or_t = TRUE;
++ continue;
++ }
++
++ /* End of arguments. */
++ if ( strcmp(*vec, "--") == 0 ) break;
++
++ /* Any other argument is not allowed. */
++ if ( *vec[0] == '-' ) return FALSE;
++ }
++
++ /* Either -f or -t must have been given. */
++ return saw_f_or_t;
++}
++
++
+ /*
+ * check_command_line() - take the command line passed to rssh, and verify
+ * that the specified command is one the user is
+@@ -275,8 +312,11 @@ char *check_command_line( char **cl, ShellOptions_t *opts )
+ return PATH_SFTP_SERVER;
+
+ if ( check_command(*cl, opts, PATH_SCP, RSSH_ALLOW_SCP) ){
+- /* filter -S option */
+- if ( opt_filter(cl, 'S') ) return NULL;
++ if ( !scp_okay(cl) ){
++ fprintf(stderr, "\ninsecure scp option not allowed.");
++ log_msg("insecure scp option in scp command line");
++ return NULL;
++ }
+ return PATH_SCP;
+ }
+
diff --git a/rssh-setuid-check.patch b/rssh-setuid-check.patch
new file mode 100644
index 0000000..5f0d3ef
--- /dev/null
+++ b/rssh-setuid-check.patch
@@ -0,0 +1,26 @@
+setuid helper ignores setuid() failure and would go on running the user's
+command as root inside the chroot
+
+diff --git a/rssh_chroot_helper.c b/rssh_chroot_helper.c
+index b751e14..6deab9e 100644
+--- a/rssh_chroot_helper.c
++++ b/rssh_chroot_helper.c
+@@ -100,7 +100,7 @@ void ch_fatal_error( char *func, char *arg, char *strerr )
+ {
+
+ /* drop privileges */
+- if ( !geteuid() ) setuid(getuid());
++ if ( !geteuid() && setuid(getuid()) == -1 ) exit(1);
+ ch_start_logging();
+
+ /* log error */
+@@ -192,7 +192,8 @@ int main( int argc, char **argv )
+
+ /* END OF CODE EXPOSED AS ROOT! */
+
+- setuid(getuid());
++ if ( setuid(getuid()) == -1 )
++ ch_fatal_error("setuid()", argv[1], strerror(errno));
+ ch_start_logging();
+
+ log_msg("user's home dir is %s", uinfo.pw_dir);
diff --git a/rssh-use-after-free.patch b/rssh-use-after-free.patch
new file mode 100644
index 0000000..3ea727e
--- /dev/null
+++ b/rssh-use-after-free.patch
@@ -0,0 +1,18 @@
+get_token() computes its return value from pointers into a buffer it has
+already freed
+
+diff --git a/rsshconf.c b/rsshconf.c
+index 4b22766..57f0df5 100644
+--- a/rsshconf.c
++++ b/rsshconf.c
+@@ -415,8 +415,9 @@ int get_token( const char *str, char *buf, const int buflen,
+ /* copy the remainder into buf, and return */
+ len = (int)(1 + end - start);
+ strncpy(buf, start, ((len > buflen - 1) ? (buflen - 1) : len));
++ len = (int)(1 + end + adjust - copy);
+ free(copy);
+- return (1 + end + adjust - copy);
++ return len;
+ }
+
+
diff --git a/rssh-userbuild.patch b/rssh-userbuild.patch
index 3871afb..c5b4224 100644
--- a/rssh-userbuild.patch
+++ b/rssh-userbuild.patch
@@ -1,8 +1,10 @@
---- rssh-2.1.1/Makefile.am.orig 2003-09-15 07:49:52.000000000 +0200
-+++ rssh-2.1.1/Makefile.am 2003-09-15 07:55:22.000000000 +0200
-@@ -15,9 +15,6 @@
+diff --git a/Makefile.am b/Makefile.am
+index c5b1a8d..82b8b21 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -18,9 +18,6 @@ base=`echo @PACKAGE_STRING@|tr " " "-"`
.c.o:
- $(CC) -c $(DEFS) $(ourdefs) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $<
+ $(CC) -c $(DEFS) $(ourdefs) $(AM_CFLAGS) $(CPPFLAGS) $(LDFLAGS) $<
-install-exec-hook:
- chmod u+s $(libexecdir)/rssh_chroot_helper
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/rssh.git/commitdiff/bb91d73bccbce90ab6745dd634a0eeca23242b1e
More information about the pld-cvs-commit
mailing list