From 42fed97b2b29b335187cc486745b6ea4d800f0f9 Mon Sep 17 00:00:00 2001 From: Michal Ruprich Date: Tue, 27 Sep 2022 11:38:52 +0200 Subject: [PATCH] Resolves: #2128682 - rsync fail with "ERROR: rejecting unrequested file-list name..." depend of parameters order --- rsync-3.2.6-filter-relative.patch | 24 ++++++ rsync-3.2.6-filter-remote.patch | 128 ++++++++++++++++++++++++++++++ rsync.spec | 9 ++- 3 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 rsync-3.2.6-filter-relative.patch create mode 100644 rsync-3.2.6-filter-remote.patch diff --git a/rsync-3.2.6-filter-relative.patch b/rsync-3.2.6-filter-relative.patch new file mode 100644 index 0000000..da7604a --- /dev/null +++ b/rsync-3.2.6-filter-relative.patch @@ -0,0 +1,24 @@ +From 464555ea923b32f3504678d05bc7de9205e5c8da Mon Sep 17 00:00:00 2001 +From: Wayne Davison +Date: Tue, 13 Sep 2022 20:56:32 -0700 +Subject: [PATCH] Fix really silly bug with --relative rules. + +--- + exclude.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/exclude.c b/exclude.c +index 4bf85cb37..b21207bab 100644 +--- a/exclude.c ++++ b/exclude.c +@@ -494,9 +494,9 @@ void add_implied_include(const char *arg, int skip_daemon_module) + maybe_add_literal_brackets_rule(rule, arg_len); + if (relative_paths && slash_cnt) { + filter_rule const *ent; +- int found = 0; + slash_cnt = 1; + for (p = new_pat + 1; (p = strchr(p, '/')) != NULL; p++) { ++ int found = 0; + *p = '\0'; + for (ent = implied_filter_list.head; ent; ent = ent->next) { + if (ent != rule && strcmp(ent->pattern, new_pat) == 0) { diff --git a/rsync-3.2.6-filter-remote.patch b/rsync-3.2.6-filter-remote.patch new file mode 100644 index 0000000..0ce8dec --- /dev/null +++ b/rsync-3.2.6-filter-remote.patch @@ -0,0 +1,128 @@ +From 950730313de994d191ba2d5be575e97690b355e8 Mon Sep 17 00:00:00 2001 +From: Wayne Davison +Date: Mon, 12 Sep 2022 22:02:00 -0700 +Subject: [PATCH] Fix bug with validing remote filter rules. + +--- + exclude.c | 35 +++++++++++++++++++++-------------- + flist.c | 2 +- + rsync.h | 1 + + 3 files changed, 23 insertions(+), 15 deletions(-) + +diff --git a/exclude.c b/exclude.c +index 5458455b3..4022e8246 100644 +--- a/exclude.c ++++ b/exclude.c +@@ -78,6 +78,10 @@ static filter_rule **mergelist_parents; + static int mergelist_cnt = 0; + static int mergelist_size = 0; + ++#define LOCAL_RULE 1 ++#define REMOTE_RULE 2 ++static uchar cur_elide_value = REMOTE_RULE; ++ + /* Each filter_list_struct describes a singly-linked list by keeping track + * of both the head and tail pointers. The list is slightly unusual in that + * a parent-dir's content can be appended to the end of the local list in a +@@ -220,6 +224,7 @@ static void add_rule(filter_rule_list *listp, const char *pat, unsigned int pat_ + slash_cnt++; + } + } ++ rule->elide = 0; + strlcpy(rule->pattern + pre_len, pat, pat_len + 1); + pat_len += pre_len; + if (suf_len) { +@@ -900,7 +905,7 @@ static int rule_matches(const char *fname, filter_rule *ex, int name_flags) + const char *strings[16]; /* more than enough */ + const char *name = fname + (*fname == '/'); + +- if (!*name) ++ if (!*name || ex->elide == cur_elide_value) + return 0; + + if (!(name_flags & NAME_IS_XATTR) ^ !(ex->rflags & FILTRULE_XATTR)) +@@ -1016,6 +1021,15 @@ int name_is_excluded(const char *fname, int name_flags, int filter_level) + return 0; + } + ++int check_server_filter(filter_rule_list *listp, enum logcode code, const char *name, int name_flags) ++{ ++ int ret; ++ cur_elide_value = LOCAL_RULE; ++ ret = check_filter(listp, code, name, name_flags); ++ cur_elide_value = REMOTE_RULE; ++ return ret; ++} ++ + /* Return -1 if file "name" is defined to be excluded by the specified + * exclude list, 1 if it is included, and 0 if it was not matched. */ + int check_filter(filter_rule_list *listp, enum logcode code, +@@ -1571,7 +1585,7 @@ char *get_rule_prefix(filter_rule *rule, const char *pat, int for_xfer, + + static void send_rules(int f_out, filter_rule_list *flp) + { +- filter_rule *ent, *prev = NULL; ++ filter_rule *ent; + + for (ent = flp->head; ent; ent = ent->next) { + unsigned int len, plen, dlen; +@@ -1586,21 +1600,15 @@ static void send_rules(int f_out, filter_rule_list *flp) + * merge files as an optimization (since they can only have + * include/exclude rules). */ + if (ent->rflags & FILTRULE_SENDER_SIDE) +- elide = am_sender ? 1 : -1; ++ elide = am_sender ? LOCAL_RULE : REMOTE_RULE; + if (ent->rflags & FILTRULE_RECEIVER_SIDE) +- elide = elide ? 0 : am_sender ? -1 : 1; ++ elide = elide ? 0 : am_sender ? REMOTE_RULE : LOCAL_RULE; + else if (delete_excluded && !elide + && (!(ent->rflags & FILTRULE_PERDIR_MERGE) + || ent->rflags & FILTRULE_NO_PREFIXES)) +- elide = am_sender ? 1 : -1; +- if (elide < 0) { +- if (prev) +- prev->next = ent->next; +- else +- flp->head = ent->next; +- } else +- prev = ent; +- if (elide > 0) ++ elide = am_sender ? LOCAL_RULE : REMOTE_RULE; ++ ent->elide = elide; ++ if (elide == LOCAL_RULE) + continue; + if (ent->rflags & FILTRULE_CVS_IGNORE + && !(ent->rflags & FILTRULE_MERGE_FILE)) { +@@ -1628,7 +1636,6 @@ static void send_rules(int f_out, filter_rule_list *flp) + if (dlen) + write_byte(f_out, '/'); + } +- flp->tail = prev; + } + + /* This is only called by the client. */ +diff --git a/flist.c b/flist.c +index 0313db542..db11b353b 100644 +--- a/flist.c ++++ b/flist.c +@@ -991,7 +991,7 @@ static struct file_struct *recv_file_entry(int f, struct file_list *flist, int x + 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) { ++ && filter_list.head && check_server_filter(&filter_list, FINFO, thisname, filt_flags) < 0) { + rprintf(FERROR, "ERROR: rejecting excluded file-list name: %s\n", thisname); + exit_cleanup(RERR_PROTOCOL); + } +diff --git a/rsync.h b/rsync.h +index f0d3dd0b4..0a5ff8090 100644 +--- a/rsync.h ++++ b/rsync.h +@@ -1024,6 +1024,7 @@ typedef struct filter_struct { + int slash_cnt; + struct filter_list_struct *mergelist; + } u; ++ uchar elide; + } filter_rule; + + typedef struct filter_list_struct { diff --git a/rsync.spec b/rsync.spec index f4a169b..f072228 100644 --- a/rsync.spec +++ b/rsync.spec @@ -9,7 +9,7 @@ Summary: A program for synchronizing files over a network Name: rsync Version: 3.2.6 -Release: 1%{?prerelease}%{?dist} +Release: 2%{?prerelease}%{?dist} URL: https://rsync.samba.org/ Source0: https://download.samba.org/pub/rsync/src/rsync-%{version}%{?prerelease}.tar.gz @@ -37,6 +37,8 @@ Provides: bundled(zlib) = 1.2.8 License: GPLv3+ Patch1: rsync-3.2.2-runtests.patch +Patch2: rsync-3.2.6-filter-relative.patch +Patch3: rsync-3.2.6-filter-remote.patch %description Rsync uses a reliable algorithm to bring remote and host files into @@ -69,6 +71,8 @@ package provides the anonymous rsync service. #%patch0 -p1 -b .verify-hostname %patch1 -p1 -b .runtests +%patch2 -p1 -b .filter-relative +%patch3 -p1 -b .filter-remote %build %configure \ @@ -119,6 +123,9 @@ install -D -m644 %{SOURCE6} $RPM_BUILD_ROOT/%{_unitdir}/rsyncd@.service %systemd_postun_with_restart rsyncd.service %changelog +* Tue Sep 27 2022 Michal Ruprich - 3.2.6-2 +- Resolves: #2128682 - rsync fail with "ERROR: rejecting unrequested file-list name..." depend of parameters order + * Mon Sep 12 2022 Michal Ruprich - 3.2.6-1 - New version 3.2.6