From b7231c7d02cfb65d291af74ff66e7d8c507ee871 Mon Sep 17 00:00:00 2001
From: Wayne Davison <wayne@opencoder.net>
Date: Sun, 31 Jul 2022 16:55:34 -0700
Subject: [PATCH] Some extra file-list safety checks.

Conflict:don't apply add_implied_include(),adapt context in flist.c,delete rsync.1.md
Reference:https://github.com/WayneD/rsync/commit/b7231c7d02cfb65d291af74ff66e7d8c507ee871
---
 exclude.c  |  4 +++-
 flist.c    | 10 ++++++++++
 main.c     |  2 ++
 receiver.c | 11 +++++++----
 4 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/exclude.c b/exclude.c
index a0090b2..684935f 100644
--- a/exclude.c
+++ b/exclude.c
@@ -45,6 +45,7 @@ filter_rule_list cvs_filter_list = { .debug_type = " [global CVS]" };
 filter_rule_list daemon_filter_list = { .debug_type = " [daemon]" };
 
 int saw_xattr_filter = 0;
+int trust_sender_filter = 0;
 
 /* Need room enough for ":MODS " prefix plus some room to grow. */
 #define MAX_RULE_PREFIX (16)
@@ -721,7 +722,7 @@ static void report_filter_result(enum logcode code, char const *name,
 			      : name_flags & NAME_IS_DIR ? "directory"
 			      : "file";
 		rprintf(code, "[%s] %sing %s %s because of pattern %s%s%s\n",
-		    w, actions[*w!='s'][!(ent->rflags & FILTRULE_INCLUDE)],
+		    w, actions[*w=='g'][!(ent->rflags & FILTRULE_INCLUDE)],
 		    t, name, ent->pattern,
 		    ent->rflags & FILTRULE_DIRECTORY ? "/" : "", type);
 	}
@@ -894,6 +895,7 @@ static filter_rule *parse_rule_tok(const char **rulestr_ptr,
 		}
 		switch (ch) {
 		case ':':
+			trust_sender_filter = 1;
 			rule->rflags |= FILTRULE_PERDIR_MERGE
 				      | FILTRULE_FINISH_SETUP;
 			/* FALL THROUGH */
diff --git a/flist.c b/flist.c
index 60e843c..0e527a7 100644
--- a/flist.c
+++ b/flist.c
@@ -70,6 +70,7 @@ extern int need_unsorted_flist;
 extern int sender_symlink_iconv;
 extern int output_needs_newline;
 extern int sender_keeps_checksum;
+extern int trust_sender_filter;
 extern int unsort_ndx;
 extern uid_t our_uid;
 extern struct stats stats;
@@ -904,6 +905,15 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x
 		exit_cleanup(RERR_UNSUPPORTED);
 	}
 
+	if (*thisname != '.' || thisname[1] != '\0') {
+		int filt_flags = S_ISDIR(mode) ? NAME_IS_DIR : NAME_IS_FILE;
+		if (!trust_sender_filter /* a per-dir filter rule means we must trust the sender's filtering */
+		 && filter_list.head && check_filter(&filter_list, FINFO, thisname, filt_flags) < 0) {
+			rprintf(FERROR, "ERROR: rejecting excluded file-list name: %s\n", thisname);
+			exit_cleanup(RERR_PROTOCOL);
+		}
+	}
+
 	if (inc_recurse && S_ISDIR(mode)) {
 		if (one_file_system) {
 			/* Room to save the dir's device for -x */
diff --git a/main.c b/main.c
index ee9630f..7561e21 100644
--- a/main.c
+++ b/main.c
@@ -78,6 +78,7 @@ extern BOOL flist_receiving_enabled;
 extern BOOL shutting_down;
 extern int backup_dir_len;
 extern int basis_dir_cnt;
+extern int trust_sender_filter;
 extern struct stats stats;
 extern char *stdout_format;
 extern char *logfile_format;
@@ -534,6 +535,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in
 #ifdef ICONV_CONST
 		setup_iconv();
 #endif
+		trust_sender_filter = 1;
 	} else if (local_server) {
 		/* If the user didn't request --[no-]whole-file, force
 		 * it on, but only if we're not batch processing. */
diff --git a/receiver.c b/receiver.c
index 6218452..147d7e5 100644
--- a/receiver.c
+++ b/receiver.c
@@ -583,10 +583,13 @@ int recv_files(int f_in, int f_out, char *local_name)
 		if (DEBUG_GTE(RECV, 1))
 			rprintf(FINFO, "recv_files(%s)\n", fname);
 
-		if (daemon_filter_list.head && (*fname != '.' || fname[1] != '\0')
-		 && check_filter(&daemon_filter_list, FLOG, fname, 0) < 0) {
-			rprintf(FERROR, "attempt to hack rsync failed.\n");
-			exit_cleanup(RERR_PROTOCOL);
+		if (daemon_filter_list.head && (*fname != '.' || fname[1] != '\0')) {
+			int filt_flags = S_ISDIR(file->mode) ? NAME_IS_DIR : NAME_IS_FILE;
+			if (check_filter(&daemon_filter_list, FLOG, fname, filt_flags) < 0) {
+				rprintf(FERROR, "ERROR: rejecting file transfer request for daemon excluded file: %s\n",
+					fname);
+				exit_cleanup(RERR_PROTOCOL);
+			}
 		}
 
 #ifdef SUPPORT_XATTRS
-- 
2.27.0

