File CVE-2019-25017.patch of Package krb5-appl.26157
From 63f3e734c633a87c745a81a49fdb3fc8881f28ff Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Mon, 11 Jan 2021 12:25:29 +0100
Subject: [PATCH 2/2] CVE-2019-25017
An issue was discovered in rcp in MIT krb5-appl through 1.0.3. Due to the rcp
implementation being derived from 1983 rcp, the server chooses which
files/directories are sent to the client. However, the rcp client only
performs cursory validation of the object name returned (only directory
traversal attacks are prevented). A malicious rcp server (or
Man-in-The-Middle attacker) can overwrite arbitrary files in the rcp
client target directory. If recursive operation (-r) is performed, the server
can manipulate subdirectories as well (for example, to overwrite
the .ssh/authorized_keys file).
Check the filenames sent by the server match those requested by the
client. This checking provides some protection against a malicious server
sending unexpected filenames, but it comes at a risk of rejecting wanted
files due to differences between client and server wildcard expansion rules.
For this reason, this also adds a new -T flag to disable the check.
Related to CVE-2019-6111 (openssh) and CVE-2019-7283 (netkit-rsh).
Signed-off-by: Samuel Cabrero <scabrero@suse.de>
---
bsd/krcp.c | 43 +++++++++++++++++++++++++++++++++++--------
bsd/rcp.M | 10 +++++++++-
2 files changed, 44 insertions(+), 9 deletions(-)
diff --git a/bsd/krcp.c b/bsd/krcp.c
index d56b40c..54095f1 100644
--- a/bsd/krcp.c
+++ b/bsd/krcp.c
@@ -46,6 +46,7 @@ char copyright[] =
#endif
#include <sys/file.h>
#include <fcntl.h>
+#include <fnmatch.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/ioctl.h>
@@ -87,7 +88,7 @@ char **save_argv(int, char **);
char *strsave();
#endif
int rcmd_stream_write(), rcmd_stream_read();
-void usage(void), sink(int, char **),
+void usage(void), sink(int, char **, const char *),
source(int, char **), rsource(char *, struct stat *), verifydir(char *);
int response(void), hosteq(char *, char *), okname(char *),
susystem(char *);
@@ -106,6 +107,7 @@ krb5_sigtype lostconn(int);
int iamremote, targetshouldbedirectory;
int iamrecursive;
int pflag;
+int Tflag;
int forcenet;
struct passwd *pwd;
int userid;
@@ -163,6 +165,7 @@ int main(argc, argv)
exit(1);
}
+ Tflag = 0;
for (argc--, argv++; argc > 0 && **argv == '-'; argc--, argv++) {
(*argv)++;
while (**argv) switch (*(*argv)++) {
@@ -175,6 +178,9 @@ int main(argc, argv)
pflag++;
break;
+ case 'T': /* Related to CVE-2019-6111. Disable filename checks */
+ Tflag++;
+ break;
case 'D':
argc--, argv++;
if (argc == 0)
@@ -236,7 +242,7 @@ int main(argc, argv)
iamremote = 1;
rcmd_stream_init_normal();
- sink(--argc, ++argv);
+ sink(--argc, ++argv, NULL);
exit(errs);
default:
@@ -548,7 +554,7 @@ int main(argc, argv)
perror("rcp seteuid user"); errs++; exit(errs);
}
}
- sink(1, argv+argc-1);
+ sink(1, argv+argc-1, src);
if (euid == 0) {
if(krb5_seteuid(0)) {
perror("rcp seteuid 0"); errs++; exit(errs);
@@ -564,7 +570,7 @@ int main(argc, argv)
if (setreuid(0, userid)) {
perror("rcp setreuid 0,user"); errs++; exit(errs);
}
- sink(1, argv+argc-1);
+ sink(1, argv+argc-1, src);
if (setreuid(userid, 0)) {
perror("rcp setreuid user,0"); errs++; exit(errs);
}
@@ -575,7 +581,7 @@ int main(argc, argv)
if(seteuid(userid)) {
perror("rcp seteuid user"); errs++; exit(errs);
}
- sink(1, argv+argc-1);
+ sink(1, argv+argc-1, src);
if(seteuid(0)) {
perror("rcp seteuid 0"); errs++; exit(errs);
}
@@ -909,9 +915,10 @@ struct timeval *tvp;
#endif
-void sink(argc, argv)
+void sink(argc, argv, src)
int argc;
char **argv;
+ const char *src;
{
mode_t mode;
mode_t mask = umask(0);
@@ -927,6 +934,7 @@ void sink(argc, argv)
char *myargv[1];
char cmdbuf[RCP_BUFSIZ], nambuf[RCP_BUFSIZ];
int setimes = 0;
+ char *src_copy = NULL, *restrict_pattern = NULL;
struct timeval tv[2];
#define atime tv[0]
#define mtime tv[1]
@@ -944,6 +952,21 @@ void sink(argc, argv)
ga();
if (stat(targ, &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFDIR)
targisdir = 1;
+ if (src != NULL && !iamrecursive && !Tflag) {
+ /*
+ * Prepare to try to restrict incoming filenames to match
+ * the requested destination file glob.
+ */
+ if ((src_copy = strdup(src)) == NULL) {
+ error("rcp: strdup failed\n");
+ exit(1);
+ }
+ if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) {
+ *restrict_pattern++ = '\0';
+ } else {
+ restrict_pattern = src_copy;
+ }
+ }
for (first = 1; ; first = 0) {
cp = cmdbuf;
if (rcmd_stream_read(rem, cp, 1, 0) <= 0)
@@ -1022,6 +1045,10 @@ void sink(argc, argv)
error("Unexpected filename: %s\n", cp);
exit(1);
}
+ if (restrict_pattern != NULL &&
+ fnmatch(restrict_pattern, cp, 0) != 0) {
+ SCREWUP("filename does not match request");
+ }
if (targisdir) {
if(strlen(targ) + strlen(cp) + 2 >= sizeof(nambuf))
SCREWUP("target name too long");
@@ -1045,7 +1072,7 @@ void sink(argc, argv)
} else if (mkdir(nambuf, mode) < 0)
goto bad;
myargv[0] = nambuf;
- sink(1, myargv);
+ sink(1, myargv, src);
if (setimes) {
setimes = 0;
if (utimes(nambuf, tv) < 0)
@@ -1186,7 +1213,7 @@ void usage()
{
#ifdef KERBEROS
fprintf(stderr,
- "Usage: \trcp [-PN | -PO] [-p] [-x] [-k realm] f1 f2; or:\n\trcp [-PN | -PO] [-r] [-p] [-x] [-k realm] f1 ... fn d2\n");
+ "Usage: \trcp [-PN | -PO] [-p] [-T] [-x] [-k realm] f1 f2; or:\n\trcp [-PN | -PO] [-r] [-p] [-T] [-x] [-k realm] f1 ... fn d2\n");
#else
fputs("usage: rcp [-p] f1 f2; or: rcp [-rp] f1 ... fn d2\n", stderr);
#endif
diff --git a/bsd/rcp.M b/bsd/rcp.M
index dcd206c..2e9b14f 100644
--- a/bsd/rcp.M
+++ b/bsd/rcp.M
@@ -22,7 +22,7 @@
rcp \- remote file copy
.SH SYNOPSIS
.B rcp
-[\fB\-p\fP] [\fB\-x\fP] [\fB\-k\fP \fIrealm\fP ] [\fB-c\fP \fIccachefile\fP] [\fB-C\fP \fIconfigfile\fP] [\fB\-D\fP \fIport\fP]
+[\fB\-p\fP] [\fB\-x\fP] [\fB\-T\fP] [\fB\-k\fP \fIrealm\fP ] [\fB-c\fP \fIccachefile\fP] [\fB-C\fP \fIconfigfile\fP] [\fB\-D\fP \fIport\fP]
[\fB\-N\fP]
[\fB\-PN | \-PO\fP]
.I file1 file2
@@ -128,6 +128,14 @@ remotely-running rcp process (started via the Kerberos remote shell
daemon) which direction files are being sent. These options should
not be used by the user. In particular, \fB-f\fP does \fBnot\fP mean
that the user's Kerberos ticket should be forwarded!
+.TP
+.B \-T
+Checks that the received filenames match those requested on the command-line
+to prevent the remote end from sending unexpected or unwanted files.
+Because of differences in how various operating systems and shells interpret
+filename wildcards, these checks may cause wanted files to be rejected.
+This option disables these checks at the expense of fully trusting that
+the server will not send unexpected filenames.
.PP
.B Rcp
handles third party copies, where neither source nor target files are on
--
2.30.0