diff --git a/rsync-3.2.4.tar.gz b/rsync-3.2.4.tar.gz deleted file mode 100644 index 1ff574b..0000000 --- a/rsync-3.2.4.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6f761838d08052b0b6579cf7f6737d93e47f01f4da04c5d24d3447b7f2a5fad1 -size 1114853 diff --git a/rsync-3.2.4.tar.gz.asc b/rsync-3.2.4.tar.gz.asc deleted file mode 100644 index aafcba1..0000000 --- a/rsync-3.2.4.tar.gz.asc +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iF0EABECAB0WIQQASMiwJtTJbw5YnC9shZ+xS5aoxQUCYlnXXQAKCRBshZ+xS5ao -xc+IAKD048bZqvc6HNIKwE1YeUe+x/46lgCfYwuhXBwgdOqeJ+5YCjfXqsAJcXw= -=QsHS ------END PGP SIGNATURE----- diff --git a/rsync-3.2.5-slp.patch b/rsync-3.2.5-slp.patch new file mode 100644 index 0000000..6bc8bce --- /dev/null +++ b/rsync-3.2.5-slp.patch @@ -0,0 +1,532 @@ +This adds Service Location Protocol support. + +To use this patch, run these commands for a successful build: + + patch -p1 rsync somehost.mydomain.com:: + +-See the following section for more details. ++And, if Service Location Protocol is available, the following will list the ++available rsync servers: ++ ++> rsync rsync:// ++ ++See the following section for even more usage details. ++ ++One more thing, if Service Location Protocol is available, the following will ++list the available rsync servers: ++ ++> rsync rsync:// ++ ++See the following section for even more usage details. + + ## SORTED TRANSFER ORDER + +diff --git a/rsync.h b/rsync.h +--- a/rsync.h ++++ b/rsync.h +@@ -234,6 +234,10 @@ + #define SIGNIFICANT_ITEM_FLAGS (~(\ + ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE)) + ++/* this is the minimum we'll use, irrespective of config setting */ ++/* definitely don't set to less than about 30 seconds */ ++#define SLP_MIN_TIMEOUT 120 ++ + #define CFN_KEEP_DOT_DIRS (1<<0) + #define CFN_KEEP_TRAILING_SLASH (1<<1) + #define CFN_DROP_TRAILING_DOT_DIR (1<<2) +diff --git a/rsyncd.conf b/rsyncd.conf +new file mode 100644 +--- /dev/null ++++ b/rsyncd.conf +@@ -0,0 +1 @@ ++slp refresh = 300 +diff --git a/rsyncd.conf.5.md b/rsyncd.conf.5.md +--- a/rsyncd.conf.5.md ++++ b/rsyncd.conf.5.md +@@ -138,6 +138,21 @@ a literal % into a value is to use %%. + You can override the default backlog value when the daemon listens for + connections. It defaults to 5. + ++0. `use slp` ++ ++ You can enable Service Location Protocol support by enabling this global ++ parameter. The default is "false". ++ ++0. `slp refresh` ++ ++ This parameter is used to determine how long service advertisements are ++ valid (measured in seconds), and is only applicable if you have Service ++ Location Protocol support compiled in. If this is not set or is set to ++ zero, then service advertisements never time out. If this is set to less ++ than 120 seconds, then 120 seconds is used. If it is set to more than ++ 65535, then 65535 is used (which is a limitation of SLP). Using 3600 ++ (one hour) is a good number if you tend to change your configuration. ++ + ## MODULE PARAMETERS + + After the global parameters you should define a number of modules, each module +@@ -1176,6 +1191,7 @@ A more sophisticated example would be: + > max connections = 4 + > syslog facility = local5 + > pid file = /var/run/rsyncd.pid ++> slp refresh = 3600 + > + > [ftp] + > path = /var/ftp/./pub +diff --git a/socket.c b/socket.c +--- a/socket.c ++++ b/socket.c +@@ -534,6 +534,16 @@ void start_accept_loop(int port, int (*fn)(int, int)) + { + fd_set deffds; + int *sp, maxfd, i; ++#ifdef HAVE_LIBSLP ++ time_t next_slp_refresh; ++ short slp_timeout = lp_use_slp() ? lp_slp_refresh() : 0; ++ if (slp_timeout) { ++ if (slp_timeout < SLP_MIN_TIMEOUT) ++ slp_timeout = SLP_MIN_TIMEOUT; ++ /* re-register before slp times out */ ++ slp_timeout -= 15; ++ } ++#endif + + #ifdef HAVE_SIGACTION + sigact.sa_flags = SA_NOCLDSTOP; +@@ -561,14 +571,25 @@ void start_accept_loop(int port, int (*fn)(int, int)) + maxfd = sp[i]; + } + ++#ifdef HAVE_LIBSLP ++ next_slp_refresh = time(NULL) + slp_timeout; ++#endif ++ + /* now accept incoming connections - forking a new process + * for each incoming connection */ + while (1) { + fd_set fds; + pid_t pid; + int fd; ++ int sel_ret; + struct sockaddr_storage addr; + socklen_t addrlen = sizeof addr; ++#ifdef HAVE_LIBSLP ++ struct timeval slp_tv; ++ ++ slp_tv.tv_sec = 10; ++ slp_tv.tv_usec = 0; ++#endif + + /* close log file before the potentially very long select so + * file can be trimmed by another process instead of growing +@@ -581,7 +602,18 @@ void start_accept_loop(int port, int (*fn)(int, int)) + fds = deffds; + #endif + +- if (select(maxfd + 1, &fds, NULL, NULL, NULL) < 1) ++#ifdef HAVE_LIBSLP ++ sel_ret = select(maxfd + 1, &fds, NULL, NULL, ++ slp_timeout ? &slp_tv : NULL); ++ if (sel_ret == 0 && slp_timeout && time(NULL) > next_slp_refresh) { ++ rprintf(FINFO, "Service registration expired, refreshing it\n"); ++ register_services(); ++ next_slp_refresh = time(NULL) + slp_timeout; ++ } ++#else ++ sel_ret = select(maxfd + 1, &fds, NULL, NULL, NULL); ++#endif ++ if (sel_ret < 1) + continue; + + for (i = 0, fd = -1; sp[i] >= 0; i++) { +diff --git a/srvloc.c b/srvloc.c +new file mode 100644 +--- /dev/null ++++ b/srvloc.c +@@ -0,0 +1,103 @@ ++/* -*- c-file-style: "linux"; -*- ++ ++ Copyright (C) 2002 by Brad Hards ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* This file implements the service location functionality */ ++/* Basically, it uses normal Service Location Protocol API */ ++ ++/* It is really a cheap hack - just to show how it might work ++ in a real application. ++*/ ++ ++#include "rsync.h" ++ ++#include ++#include ++#include ++ ++/* This one just prints out the attributes */ ++static SLPBoolean getAttrCallback(UNUSED(SLPHandle hslp), const char *attrlist, ++ SLPError errcode, UNUSED(void *cookie)) ++{ ++ char *cleanstr; ++ ++ if (errcode == SLP_OK) { ++ if (!strcmp(attrlist, "(comment=)")) ++ rprintf(FINFO, "\t(No description)\n"); ++ else { ++ cleanstr = strrchr(attrlist, ')') ; ++ *cleanstr = ' '; /* remove last ')' */ ++ rprintf(FINFO, "\t%s\n", strchr(attrlist, '=') + 1); ++ } ++ } ++ return SLP_FALSE; ++} ++ ++static SLPBoolean getSLPSrvURLCallback(UNUSED(SLPHandle hslp), ++ const char *srvurl, UNUSED(unsigned short lifetime), ++ SLPError errcode, void *cookie) ++{ ++ SLPError result; ++ SLPHandle attrhslp; ++ ++ if (errcode == SLP_OK) { ++ /* chop service: off the front */ ++ rprintf(FINFO, " %s ", (strchr(srvurl, ':') + 1)); ++ /* check for any attributes */ ++ if (SLPOpen("en", SLP_FALSE,&attrhslp) == SLP_OK) { ++ result = SLPFindAttrs(attrhslp, srvurl, ++ "", /* return all attributes */ ++ "", /* use configured scopes */ ++ getAttrCallback, NULL); ++ if (result != SLP_OK) { ++ rprintf(FERROR, "errorcode: %i\n",result); ++ } ++ SLPClose(attrhslp); ++ } ++ *(SLPError*)cookie = SLP_OK; ++ } else ++ *(SLPError*)cookie = errcode; ++ ++ /* Return SLP_TRUE because we want to be called again ++ * if more services were found. */ ++ ++ return SLP_TRUE; ++} ++ ++int print_service_list(void) ++{ ++ SLPError err; ++ SLPError callbackerr; ++ SLPHandle hslp; ++ ++ err = SLPOpen("en",SLP_FALSE,&hslp); ++ if (err != SLP_OK) { ++ rprintf(FERROR, "Error opening slp handle %i\n", err); ++ return err; ++ } ++ ++ SLPFindSrvs(hslp, "rsync", ++ 0, /* use configured scopes */ ++ 0, /* no attr filter */ ++ getSLPSrvURLCallback, &callbackerr); ++ ++ /* Now that we're done using slp, close the slp handle */ ++ SLPClose(hslp); ++ ++ return 0; ++} +diff --git a/srvreg.c b/srvreg.c +new file mode 100644 +--- /dev/null ++++ b/srvreg.c +@@ -0,0 +1,128 @@ ++/* -*- c-file-style: "linux"; -*- ++ ++ Copyright (C) 2002 by Brad Hards ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++*/ ++ ++/* This file implements the service registration functionality */ ++ ++/* Basically, it uses normal Service Location Protocol API */ ++ ++#include "rsync.h" ++#include "slp.h" ++#include "netdb.h" ++ ++extern int rsync_port; ++ ++static void slp_callback(UNUSED(SLPHandle hslp), SLPError errcode, void *cookie) ++{ ++ /* return the error code in the cookie */ ++ *(SLPError*)cookie = errcode; ++ ++ /* You could do something else here like print out ++ * the errcode, etc. Remember, as a general rule, ++ * do not try to do too much in a callback because ++ * it is being executed by the same thread that is ++ * reading slp packets from the wire. */ ++} ++ ++int register_services(void) ++{ ++ SLPError err, callbackerr; ++ SLPHandle hslp; ++ int n; ++ int i; ++ char srv[120]; ++ char attr[120]; ++ char localhost[256]; ++ extern char *config_file; ++ short timeout; ++ struct addrinfo aih, *ai = 0; ++ ++ if (!lp_load(config_file, 0)) { ++ exit_cleanup(RERR_SYNTAX); ++ } ++ ++ n = lp_num_modules(); ++ ++ if (0 == lp_slp_refresh()) ++ timeout = SLP_LIFETIME_MAXIMUM; /* don't expire, ever */ ++ else if (SLP_MIN_TIMEOUT > lp_slp_refresh()) ++ timeout = SLP_MIN_TIMEOUT; /* use a reasonable minimum */ ++ else if (SLP_LIFETIME_MAXIMUM <= lp_slp_refresh()) ++ timeout = (SLP_LIFETIME_MAXIMUM - 1); /* as long as possible */ ++ else ++ timeout = lp_slp_refresh(); ++ ++ rprintf(FINFO, "rsyncd registering %d service%s with slpd for %d seconds:\n", n, ((n==1)? "":"s"), timeout); ++ err = SLPOpen("en",SLP_FALSE,&hslp); ++ if (err != SLP_OK) { ++ rprintf(FINFO, "Error opening slp handle %i\n",err); ++ return err; ++ } ++ if (gethostname(localhost, sizeof localhost)) { ++ rprintf(FINFO, "Could not get hostname: %s\n", strerror(errno)); ++ return err; ++ } ++ memset(&aih, 0, sizeof aih); ++ aih.ai_family = PF_UNSPEC; ++ aih.ai_flags = AI_CANONNAME; ++ if (0 != (err = getaddrinfo(localhost, 0, &aih, &ai)) || !ai) { ++ rprintf(FINFO, "Could not resolve hostname: %s\n", gai_strerror(err)); ++ return err; ++ } ++ /* Register each service with SLP */ ++ for (i = 0; i < n; i++) { ++ if (!lp_list(i)) ++ continue; ++ ++ snprintf(srv, sizeof srv, "service:rsync://%s:%d/%s", ++ ai->ai_canonname, ++ rsync_port, ++ lp_name(i)); ++ rprintf(FINFO, " %s\n", srv); ++ if (lp_comment(i)) { ++ snprintf(attr, sizeof attr, "(comment=%s)", ++ lp_comment(i)); ++ } ++ err = SLPReg(hslp, ++ srv, /* service to register */ ++ timeout, ++ 0, /* this is ignored */ ++ attr, /* attributes */ ++ SLP_TRUE, /* new registration - don't change this */ ++ slp_callback, /* callback */ ++ &callbackerr); ++ ++ /* err may contain an error code that occurred as the slp library ++ * _prepared_ to make the call. */ ++ if (err != SLP_OK || callbackerr != SLP_OK) ++ rprintf(FINFO, "Error registering service with slp %i\n", err); ++ ++ /* callbackerr may contain an error code (that was assigned through ++ * the callback cookie) that occurred as slp packets were sent on ++ * the wire. */ ++ if (callbackerr != SLP_OK) ++ rprintf(FINFO, "Error registering service with slp %i\n",callbackerr); ++ } ++ ++ /* Now that we're done using slp, close the slp handle */ ++ freeaddrinfo(ai); ++ SLPClose(hslp); ++ ++ /* refresh is done in main select loop */ ++ return 0; ++} +diff --git a/usage.c b/usage.c +--- a/usage.c ++++ b/usage.c +@@ -137,6 +137,11 @@ static void print_info_flags(enum logcode f) + #endif + "crtimes", + ++#ifndef HAVE_LIBSLP ++ "no " ++#endif ++ "SLP", ++ + "*Optimizations", + + #ifndef USE_ROLL_SIMD diff --git a/rsync-3.2.5.tar.gz b/rsync-3.2.5.tar.gz new file mode 100644 index 0000000..e8d7eb5 --- /dev/null +++ b/rsync-3.2.5.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ac4d21635cdf791867bc377c35ca6dda7f50d919a58be45057fd51600c69aba +size 1129957 diff --git a/rsync-3.2.5.tar.gz.asc b/rsync-3.2.5.tar.gz.asc new file mode 100644 index 0000000..e015380 --- /dev/null +++ b/rsync-3.2.5.tar.gz.asc @@ -0,0 +1,6 @@ +-----BEGIN PGP SIGNATURE----- + +iF0EABECAB0WIQQASMiwJtTJbw5YnC9shZ+xS5aoxQUCYvlODgAKCRBshZ+xS5ao +xT3cAKC07We0q6kVJHbFJ53XkC7a+vE41gCguSxuuVS2LJPmwpZRxAEp6bH84vY= +=IsqH +-----END PGP SIGNATURE----- diff --git a/rsync-CVE-2022-29154.patch b/rsync-CVE-2022-29154.patch deleted file mode 100644 index 07fdbda..0000000 --- a/rsync-CVE-2022-29154.patch +++ /dev/null @@ -1,399 +0,0 @@ -From b7231c7d02cfb65d291af74ff66e7d8c507ee871 Mon Sep 17 00:00:00 2001 -From: Wayne Davison -Date: Sun, 31 Jul 2022 16:55:34 -0700 -Subject: [PATCH] Some extra file-list safety checks. - ---- - exclude.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++++- - flist.c | 17 ++++++- - io.c | 4 ++ - main.c | 7 ++- - receiver.c | 11 +++-- - rsync.1.md | 44 ++++++++++++++++-- - 6 files changed, 202 insertions(+), 11 deletions(-) - -Index: rsync-3.2.4/exclude.c -=================================================================== ---- rsync-3.2.4.orig/exclude.c -+++ rsync-3.2.4/exclude.c -@@ -27,16 +27,22 @@ extern int am_server; - extern int am_sender; - extern int eol_nulls; - extern int io_error; -+extern int xfer_dirs; -+extern int recurse; - extern int local_server; - extern int prune_empty_dirs; - extern int ignore_perishable; -+extern int old_style_args; -+extern int relative_paths; - extern int delete_mode; - extern int delete_excluded; - extern int cvs_exclude; - extern int sanitize_paths; - extern int protocol_version; -+extern int list_only; - extern int module_id; - -+extern char *filesfrom_host; - extern char curr_dir[MAXPATHLEN]; - extern unsigned int curr_dir_len; - extern unsigned int module_dirlen; -@@ -44,8 +50,10 @@ extern unsigned int module_dirlen; - filter_rule_list filter_list = { .debug_type = "" }; - filter_rule_list cvs_filter_list = { .debug_type = " [global CVS]" }; - filter_rule_list daemon_filter_list = { .debug_type = " [daemon]" }; -+filter_rule_list implied_filter_list = { .debug_type = " [implied]" }; - - 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) -@@ -292,6 +300,125 @@ static void add_rule(filter_rule_list *l - } - } - -+/* Each arg the client sends to the remote sender turns into an implied include -+ * that the receiver uses to validate the file list from the sender. */ -+void add_implied_include(const char *arg) -+{ -+ filter_rule *rule; -+ int arg_len, saw_wild = 0, backslash_cnt = 0; -+ int slash_cnt = 1; /* We know we're adding a leading slash. */ -+ const char *cp; -+ char *p; -+ if (old_style_args || list_only || filesfrom_host != NULL) -+ return; -+ if (relative_paths) { -+ cp = strstr(arg, "/./"); -+ if (cp) -+ arg = cp+3; -+ } else { -+ if ((cp = strrchr(arg, '/')) != NULL) -+ arg = cp + 1; -+ } -+ arg_len = strlen(arg); -+ if (arg_len) { -+ if (strpbrk(arg, "*[?")) { -+ /* We need to add room to escape backslashes if wildcard chars are present. */ -+ cp = arg; -+ while ((cp = strchr(cp, '\\')) != NULL) { -+ arg_len++; -+ cp++; -+ } -+ saw_wild = 1; -+ } -+ arg_len++; /* Leave room for the prefixed slash */ -+ rule = new0(filter_rule); -+ if (!implied_filter_list.head) -+ implied_filter_list.head = implied_filter_list.tail = rule; -+ else { -+ rule->next = implied_filter_list.head; -+ implied_filter_list.head = rule; -+ } -+ rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0); -+ p = rule->pattern = new_array(char, arg_len + 1); -+ *p++ = '/'; -+ cp = arg; -+ while (*cp) { -+ switch (*cp) { -+ case '\\': -+ backslash_cnt++; -+ if (saw_wild) -+ *p++ = '\\'; -+ *p++ = *cp++; -+ break; -+ case '/': -+ if (p[-1] == '/') /* This is safe because of the initial slash. */ -+ break; -+ if (relative_paths) { -+ filter_rule const *ent; -+ int found = 0; -+ *p = '\0'; -+ for (ent = implied_filter_list.head; ent; ent = ent->next) { -+ if (ent != rule && strcmp(ent->pattern, rule->pattern) == 0) -+ found = 1; -+ } -+ if (!found) { -+ filter_rule *R_rule = new0(filter_rule); -+ R_rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0); -+ R_rule->pattern = strdup(rule->pattern); -+ R_rule->u.slash_cnt = slash_cnt; -+ R_rule->next = implied_filter_list.head; -+ implied_filter_list.head = R_rule; -+ } -+ } -+ slash_cnt++; -+ *p++ = *cp++; -+ break; -+ default: -+ *p++ = *cp++; -+ break; -+ } -+ } -+ *p = '\0'; -+ rule->u.slash_cnt = slash_cnt; -+ arg = (const char *)rule->pattern; -+ } -+ -+ if (recurse || xfer_dirs) { -+ /* Now create a rule with an added "/" & "**" or "*" at the end */ -+ rule = new0(filter_rule); -+ if (recurse) -+ rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD | FILTRULE_WILD2; -+ else -+ rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD; -+ /* A +4 in the len leaves enough room for / * * \0 or / * \0 \0 */ -+ if (!saw_wild && backslash_cnt) { -+ /* We are appending a wildcard, so now the backslashes need to be escaped. */ -+ p = rule->pattern = new_array(char, arg_len + backslash_cnt + 3 + 1); -+ cp = arg; -+ while (*cp) { -+ if (*cp == '\\') -+ *p++ = '\\'; -+ *p++ = *cp++; -+ } -+ } else { -+ p = rule->pattern = new_array(char, arg_len + 3 + 1); -+ if (arg_len) { -+ memcpy(p, arg, arg_len); -+ p += arg_len; -+ } -+ } -+ if (p[-1] != '/') -+ *p++ = '/'; -+ *p++ = '*'; -+ if (recurse) -+ *p++ = '*'; -+ *p = '\0'; -+ rule->u.slash_cnt = slash_cnt + 1; -+ rule->next = implied_filter_list.head; -+ implied_filter_list.head = rule; -+ } -+} -+ - /* This frees any non-inherited items, leaving just inherited items on the list. */ - static void pop_filter_list(filter_rule_list *listp) - { -@@ -718,7 +845,7 @@ static void report_filter_result(enum lo - : 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); - } -@@ -890,6 +1017,7 @@ static filter_rule *parse_rule_tok(const - } - switch (ch) { - case ':': -+ trust_sender_filter = 1; - rule->rflags |= FILTRULE_PERDIR_MERGE - | FILTRULE_FINISH_SETUP; - /* FALL THROUGH */ -Index: rsync-3.2.4/flist.c -=================================================================== ---- rsync-3.2.4.orig/flist.c -+++ rsync-3.2.4/flist.c -@@ -73,6 +73,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; -@@ -83,8 +84,7 @@ extern char curr_dir[MAXPATHLEN]; - - extern struct chmod_mode_struct *chmod_modes; - --extern filter_rule_list filter_list; --extern filter_rule_list daemon_filter_list; -+extern filter_rule_list filter_list, implied_filter_list, daemon_filter_list; - - #ifdef ICONV_OPTION - extern int filesfrom_convert; -@@ -986,6 +986,19 @@ static struct file_struct *recv_file_ent - 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 (implied_filter_list.head && check_filter(&implied_filter_list, FINFO, thisname, filt_flags) <= 0) { -+ rprintf(FERROR, "ERROR: rejecting unrequested 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 */ -Index: rsync-3.2.4/io.c -=================================================================== ---- rsync-3.2.4.orig/io.c -+++ rsync-3.2.4/io.c -@@ -419,6 +419,7 @@ static void forward_filesfrom_data(void) - while (s != eob) { - if (*s++ == '\0') { - ff_xb.len = s - sob - 1; -+ add_implied_include(sob); - if (iconvbufs(ic_send, &ff_xb, &iobuf.out, flags) < 0) - exit_cleanup(RERR_PROTOCOL); /* impossible? */ - write_buf(iobuf.out_fd, s-1, 1); /* Send the '\0'. */ -@@ -450,9 +451,12 @@ static void forward_filesfrom_data(void) - char *f = ff_xb.buf + ff_xb.pos; - char *t = ff_xb.buf; - char *eob = f + len; -+ char *cur = t; - /* Eliminate any multi-'\0' runs. */ - while (f != eob) { - if (!(*t++ = *f++)) { -+ add_implied_include(cur); -+ cur = t; - while (f != eob && *f == '\0') - f++; - } -Index: rsync-3.2.4/main.c -=================================================================== ---- rsync-3.2.4.orig/main.c -+++ rsync-3.2.4/main.c -@@ -89,6 +89,7 @@ extern int backup_dir_len; - extern int basis_dir_cnt; - extern int default_af_hint; - extern int stdout_format_has_i; -+extern int trust_sender_filter; - extern struct stats stats; - extern char *stdout_format; - extern char *logfile_format; -@@ -104,7 +105,7 @@ extern char curr_dir[MAXPATHLEN]; - extern char backup_dir_buf[MAXPATHLEN]; - extern char *basis_dir[MAX_BASIS_DIRS+1]; - extern struct file_list *first_flist; --extern filter_rule_list daemon_filter_list; -+extern filter_rule_list daemon_filter_list, implied_filter_list; - - uid_t our_uid; - gid_t our_gid; -@@ -635,6 +636,7 @@ static pid_t do_cmd(char *cmd, char *mac - #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. */ -@@ -1516,6 +1518,8 @@ static int start_client(int argc, char * - char *dummy_host; - int dummy_port = rsync_port; - int i; -+ if (filesfrom_fd < 0) -+ add_implied_include(remote_argv[0]); - /* For remote source, any extra source args must have either - * the same hostname or an empty hostname. */ - for (i = 1; i < remote_argc; i++) { -@@ -1539,6 +1543,7 @@ static int start_client(int argc, char * - if (!rsync_port && !*arg) /* Turn an empty arg into a dot dir. */ - arg = "."; - remote_argv[i] = arg; -+ add_implied_include(arg); - } - } - -Index: rsync-3.2.4/receiver.c -=================================================================== ---- rsync-3.2.4.orig/receiver.c -+++ rsync-3.2.4/receiver.c -@@ -593,10 +593,13 @@ int recv_files(int f_in, int f_out, char - 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 -Index: rsync-3.2.4/rsync.1.md -=================================================================== ---- rsync-3.2.4.orig/rsync.1.md -+++ rsync-3.2.4/rsync.1.md -@@ -308,6 +308,35 @@ separate the files into different rsync - [`--delay-updates`](#opt) (which doesn't affect the sorted transfer order, but - does make the final file-updating phase happen much more rapidly). - -+## MULTI-HOST SECURITY -+ -+Rsync takes steps to ensure that the file requests that are shared in a -+transfer are protected against various security issues. Most of the potential -+problems arise on the receiving side where rsync takes steps to ensure that the -+list of files being transferred remains within the bounds of what was -+requested. -+ -+Toward this end, rsync 3.1.2 and later have aborted when a file list contains -+an absolute or relative path that tries to escape out of the top of the -+transfer. Also, beginning with version 3.2.5 (or a version patched against -+CVE-2022-29154), rsync does two more safety checks of the file list to (1) -+ensure that no extra source arguments were added into the transfer other than -+those that the client requested and (2) ensure that the file list obeys the -+exclude rules that we sent to the sender. -+ -+For those that don't yet have a 3.2.5 (or a version patched against -+CVE-2022-29154) client rsync, it is safest to do a copy into a dedicated -+destination directory for the remote files rather than requesting the remote -+content get mixed in with other local content. For example, doing an rsync copy -+into your home directory is potentially unsafe on an older rsync if the remote -+rsync is being controlled by a bad actor: -+ -+> rsync -aiv host1:dir1 ~ -+ -+A safer command would be: -+ -+> rsync -aiv host1:dir1 ~/host1-files -+ - ## EXAMPLES - - Here are some examples of how I use rsync. -@@ -2335,6 +2364,12 @@ your home directory (remove the '=' for - behavior. The environment is always overridden by manually specified - positive or negative options (the negative is `--no-old-args`). - -+ Note that this option also disables the extra safety check added in 3.2.5 -+ (or a version patched against CVE-2022-29154) that ensures that a remote -+ sender isn't including extra top-level items in the file-list that you -+ didn't request. This side-effect is necessary because we can't know for -+ sure what names to expect when the remote shell is interpreting the args. -+ - This option conflicts with the [`--protect-args`](#opt) option. - - 0. `--protect-args`, `-s` -@@ -3766,8 +3801,13 @@ available rule prefixes: - - 0. `exclude, '-'` specifies an exclude pattern. - 0. `include, '+'` specifies an include pattern. --0. `merge, '.'` specifies a merge-file to read for more rules. --0. `dir-merge, ':'` specifies a per-directory merge-file. -+0. `merge, '.'` specifies a merge-file on the client side to read for more -+ rules. -+0. `dir-merge, ':'` specifies a per-directory merge-file. Using this kind of -+ filter rule requires that you trust the sending side's filter checking, and -+ thus it disables the receiver's verification of the file-list names against -+ the filter rules (since only the sender can know for sure if it obeyed all -+ the filter rules when some are per-dir merged from the sender's files). - 0. `hide, 'H'` specifies a pattern for hiding files from the transfer. - 0. `show, 'S'` files that match the pattern are not hidden. - 0. `protect, 'P'` specifies a pattern for protecting files from deletion. diff --git a/rsync-patches-3.2.4.tar.gz b/rsync-patches-3.2.4.tar.gz deleted file mode 100644 index 9ad441d..0000000 --- a/rsync-patches-3.2.4.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:70a597590af6c61cf3d05d663429ff9f60ffe24e44f9c73a4cdc69ebdc1322a4 -size 133580 diff --git a/rsync-patches-3.2.4.tar.gz.asc b/rsync-patches-3.2.4.tar.gz.asc deleted file mode 100644 index 528112d..0000000 --- a/rsync-patches-3.2.4.tar.gz.asc +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iF0EABECAB0WIQQASMiwJtTJbw5YnC9shZ+xS5aoxQUCYlnXXQAKCRBshZ+xS5ao -xa40AJ9nhXAe+WGpq+hCo6D9TGPNDmKsWwCfR5dNecRPJBCsiffMAJXQUr7Mfg0= -=jE+s ------END PGP SIGNATURE----- diff --git a/rsync-patches-3.2.5.tar.gz b/rsync-patches-3.2.5.tar.gz new file mode 100644 index 0000000..fbfff84 --- /dev/null +++ b/rsync-patches-3.2.5.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7b1fdf1fc0fca68fd254246c2dc04f6ac90241e665dcf9dfc21dccd8270b6bb +size 141521 diff --git a/rsync-patches-3.2.5.tar.gz.asc b/rsync-patches-3.2.5.tar.gz.asc new file mode 100644 index 0000000..ca54873 --- /dev/null +++ b/rsync-patches-3.2.5.tar.gz.asc @@ -0,0 +1,6 @@ +-----BEGIN PGP SIGNATURE----- + +iF0EABECAB0WIQQASMiwJtTJbw5YnC9shZ+xS5aoxQUCYvkwjgAKCRBshZ+xS5ao +xWAMAKC8sGretqzHSgTCOW8eCO/pFwh5DQCeJTD+07rzAvXt3HnJKvor9D3/jF4= +=UjDZ +-----END PGP SIGNATURE----- diff --git a/rsync.changes b/rsync.changes index cef069f..6bf7837 100644 --- a/rsync.changes +++ b/rsync.changes @@ -1,9 +1,56 @@ +------------------------------------------------------------------- +Tue Aug 16 08:19:20 UTC 2022 - David Anes + +- Add upstream patch rsync-3.2.5-slp.patch, as the one included in + the released tarball doesn't fully apply. + +- Drop patch rsync-CVE-2022-29154.patch, already included upstream. + +- Update to 3.2.5 + * SECURITY FIXES: + - Added some file-list safety checking that helps to ensure that a rogue + sending rsync can't add unrequested top-level names and/or include recursive + names that should have been excluded by the sender. These extra safety + checks only require the receiver rsync to be updated. When dealing with an + untrusted sending host, it is safest to copy into a dedicated destination + directory for the remote content (i.e. don't copy into a destination + directory that contains files that aren't from the remote host unless you + trust the remote host). Fixes CVE-2022-29154. + - A fix for CVE-2022-37434 in the bundled zlib (buffer overflow issue). + * BUG FIXES: + - Fixed the handling of filenames specified with backslash-quoted wildcards + when the default remote-arg-escaping is enabled. + - Fixed the configure check for signed char that was causing a host that + defaults to unsigned characters to generate bogus rolling checksums. This + made rsync send mostly literal data for a copy instead of finding matching + data in the receiver's basis file (for a file that contains high-bit + characters). + - Lots of manpage improvements, including an attempt to better describe how + include/exclude filters work. + - If rsync is compiled with an xxhash 0.8 library and then moved to a system + with a dynamically linked xxhash 0.7 library, we now detect this and disable + the XX3 hashes (since these routines didn't stabilize until 0.8). + * ENHANCEMENTS: + - The [`--trust-sender`](rsync.1#opt) option was added as a way to bypass the + extra file-list safety checking (should that be required). + * PACKAGING RELATED: + - A note to those wanting to patch older rsync versions: the changes in this + release requires the quoted argument change from 3.2.4. Then, you'll want + every single code change from 3.2.5 since there is no fluff in this release. + - The build date that goes into the manpages is now based on the developer's + release date, not on the build's local-timezone interpretation of the date. + * DEVELOPER RELATED: + - Configure now defaults GETGROUPS_T to gid_t when cross compiling. + - Configure now looks for the bsd/string.h include file in order to fix the + build on a host that has strlcpy() in the main libc but not defined in the + main string.h file. + ------------------------------------------------------------------- Mon Aug 1 12:27:43 UTC 2022 - David Anes - Security fix: [bsc#1201840, CVE-2022-29154] * arbitrary file write vulnerability via do_server_recv function - * Added patch rsync-rsync-CVE-2022-29154.patch + * Added patch rsync-CVE-2022-29154.patch ------------------------------------------------------------------- Tue Jun 21 10:34:12 UTC 2022 - Stefan Schubert diff --git a/rsync.spec b/rsync.spec index 9067d1c..4a679d5 100644 --- a/rsync.spec +++ b/rsync.spec @@ -23,7 +23,7 @@ %endif Name: rsync -Version: 3.2.4 +Version: 3.2.5 Release: 0 Summary: Versatile tool for fast incremental file transfer License: GPL-3.0-or-later @@ -41,8 +41,11 @@ Source9: rsyncd@.service Source10: http://rsync.samba.org/ftp/rsync/src/rsync-%{version}.tar.gz.asc Source11: http://rsync.samba.org/ftp/rsync/src/rsync-patches-%{version}.tar.gz.asc Source12: %{name}.keyring +# PATCH-FIX-UPSTREAM: slp.diff included in distribution tar file does not apply +# cleanly, therefore we use the upstream patch directly (for 3.2.5) +Source13: https://raw.githubusercontent.com/WayneD/rsync-patches/d899304ea5daa125417f296bdd6f8bff0ed342ca/slp.diff#:/rsync-3.2.5-slp.patch Patch0: rsync-no-libattr.patch -Patch1: rsync-CVE-2022-29154.patch +Patch1: rsync-3.2.5-slp.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: c++_compiler @@ -76,7 +79,11 @@ for backups and mirroring and as an improved copy command for everyday use. %setup -q -b 1 rm -f zlib/*.h -patch -p1 < patches/slp.diff +# TODO: (See Source13/Patch1) we have to re-enable the patching of SLP using +# the patch included in the distributed tar file for next version, for now +# we apply latest upstream patch (for 3.2.5) from Github, the one included +# in tar fiel desn't apply cleanly +# patch -p1 < patches/slp.diff %autopatch -p1