117 lines
4.1 KiB
Diff
117 lines
4.1 KiB
Diff
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 e095744..ab91999 100644
|
|
--- a/exclude.c
|
|
+++ b/exclude.c
|
|
@@ -46,6 +46,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)
|
|
@@ -714,7 +715,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);
|
|
}
|
|
@@ -886,6 +887,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 5a1e424..5d5c7a2 100644
|
|
--- a/flist.c
|
|
+++ b/flist.c
|
|
@@ -72,6 +72,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;
|
|
@@ -971,6 +972,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 46b97b5..c688e6d 100644
|
|
--- a/main.c
|
|
+++ b/main.c
|
|
@@ -87,6 +87,7 @@ extern BOOL shutting_down;
|
|
extern int backup_dir_len;
|
|
extern int basis_dir_cnt;
|
|
extern int default_af_hint;
|
|
+extern int trust_sender_filter;
|
|
extern struct stats stats;
|
|
extern char *stdout_format;
|
|
extern char *logfile_format;
|
|
@@ -642,6 +643,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 9df603f..3182e2d 100644
|
|
--- a/receiver.c
|
|
+++ b/receiver.c
|
|
@@ -584,10 +584,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
|
|
|