Compare commits
No commits in common. "c8" and "c8s" have entirely different histories.
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
SOURCES/rsync-3.1.3.tar.gz
|
SOURCES/rsync-3.1.3.tar.gz
|
||||||
SOURCES/rsync-patches-3.1.3.tar.gz
|
SOURCES/rsync-patches-3.1.3.tar.gz
|
||||||
|
/rsync-3.1.3.tar.gz
|
||||||
|
/rsync-patches-3.1.3.tar.gz
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
82e7829c0b3cefbd33c233005341e2073c425629 SOURCES/rsync-3.1.3.tar.gz
|
|
||||||
74c16510a18ef43d797f9ceba6150f0862568cc0 SOURCES/rsync-patches-3.1.3.tar.gz
|
|
@ -1,14 +0,0 @@
|
|||||||
diff --git a/match.c b/match.c
|
|
||||||
index 36e78ed..dfd6af2 100644
|
|
||||||
--- a/match.c
|
|
||||||
+++ b/match.c
|
|
||||||
@@ -147,6 +147,9 @@ static void hash_search(int f,struct sum_struct *s,
|
|
||||||
int more;
|
|
||||||
schar *map;
|
|
||||||
|
|
||||||
+ // prevent possible memory leaks
|
|
||||||
+ memset(sum2, 0, sizeof sum2);
|
|
||||||
+
|
|
||||||
/* want_i is used to encourage adjacent matches, allowing the RLL
|
|
||||||
* coding of the output to work more efficiently. */
|
|
||||||
want_i = 0;
|
|
@ -1,36 +0,0 @@
|
|||||||
diff --git a/flist.c b/flist.c
|
|
||||||
index 464d556..087f9da 100644
|
|
||||||
--- a/flist.c
|
|
||||||
+++ b/flist.c
|
|
||||||
@@ -2584,6 +2584,19 @@ struct file_list *recv_file_list(int f, int dir_ndx)
|
|
||||||
init_hard_links();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
+ if (inc_recurse && dir_ndx >= 0) {
|
|
||||||
+ if (dir_ndx >= dir_flist->used) {
|
|
||||||
+ rprintf(FERROR_XFER, "rsync: refusing invalid dir_ndx %u >= %u\n", dir_ndx, dir_flist->used);
|
|
||||||
+ exit_cleanup(RERR_PROTOCOL);
|
|
||||||
+ }
|
|
||||||
+ struct file_struct *file = dir_flist->files[dir_ndx];
|
|
||||||
+ if (file->flags & FLAG_GOT_DIR_FLIST) {
|
|
||||||
+ rprintf(FERROR_XFER, "rsync: refusing malicious duplicate flist for dir %d\n", dir_ndx);
|
|
||||||
+ exit_cleanup(RERR_PROTOCOL);
|
|
||||||
+ }
|
|
||||||
+ file->flags |= FLAG_GOT_DIR_FLIST;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
flist = flist_new(0, "recv_file_list");
|
|
||||||
|
|
||||||
if (inc_recurse) {
|
|
||||||
diff --git a/rsync.h b/rsync.h
|
|
||||||
index b357dad..bc9abac 100644
|
|
||||||
--- a/rsync.h
|
|
||||||
+++ b/rsync.h
|
|
||||||
@@ -83,6 +83,7 @@
|
|
||||||
#define FLAG_SKIP_GROUP (1<<10) /* receiver/generator */
|
|
||||||
#define FLAG_TIME_FAILED (1<<11)/* generator */
|
|
||||||
#define FLAG_MOD_NSEC (1<<12) /* sender/receiver/generator */
|
|
||||||
+#define FLAG_GOT_DIR_FLIST (1<<13)/* sender/receiver/generator - dir_flist only */
|
|
||||||
|
|
||||||
/* These flags are passed to functions but not stored. */
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
|||||||
diff --git a/testsuite/unsafe-byname.test b/testsuite/unsafe-byname.test
|
|
||||||
index 75e7201..d2e318e 100644
|
|
||||||
--- a/testsuite/unsafe-byname.test
|
|
||||||
+++ b/testsuite/unsafe-byname.test
|
|
||||||
@@ -40,7 +40,7 @@ test_unsafe ..//../dest from/dir unsafe
|
|
||||||
test_unsafe .. from/file safe
|
|
||||||
test_unsafe ../.. from/file unsafe
|
|
||||||
test_unsafe ..//.. from//file unsafe
|
|
||||||
-test_unsafe dir/.. from safe
|
|
||||||
+test_unsafe dir/.. from unsafe
|
|
||||||
test_unsafe dir/../.. from unsafe
|
|
||||||
test_unsafe dir/..//.. from unsafe
|
|
||||||
|
|
||||||
diff --git a/util.c b/util.c
|
|
||||||
index da50ff1..f260d39 100644
|
|
||||||
--- a/util.c
|
|
||||||
+++ b/util.c
|
|
||||||
@@ -1318,7 +1318,14 @@ int handle_partial_dir(const char *fname, int create)
|
|
||||||
*
|
|
||||||
* "src" is the top source directory currently applicable at the level
|
|
||||||
* of the referenced symlink. This is usually the symlink's full path
|
|
||||||
- * (including its name), as referenced from the root of the transfer. */
|
|
||||||
+ * (including its name), as referenced from the root of the transfer.
|
|
||||||
+ *
|
|
||||||
+ * NOTE: this also rejects dest names with a .. component in other
|
|
||||||
+ * than the first component of the name ie. it rejects names such as
|
|
||||||
+ * a/b/../x/y. This needs to be done as the leading subpaths 'a' or
|
|
||||||
+ * 'b' could later be replaced with symlinks such as a link to '.'
|
|
||||||
+ * resulting in the link being transferred now becoming unsafe
|
|
||||||
+ */
|
|
||||||
int unsafe_symlink(const char *dest, const char *src)
|
|
||||||
{
|
|
||||||
const char *name, *slash;
|
|
||||||
@@ -1328,6 +1335,23 @@ int unsafe_symlink(const char *dest, const char *src)
|
|
||||||
if (!dest || !*dest || *dest == '/')
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
+ // reject destinations with /../ in the name other than at the start of the name
|
|
||||||
+ const char *dest2 = dest;
|
|
||||||
+ while (strncmp(dest2, "../", 3) == 0) {
|
|
||||||
+ dest2 += 3;
|
|
||||||
+ while (*dest2 == '/') {
|
|
||||||
+ // allow for ..//..///../foo
|
|
||||||
+ dest2++;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (strstr(dest2, "/../"))
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
+ // reject if the destination ends in /..
|
|
||||||
+ const size_t dlen = strlen(dest);
|
|
||||||
+ if (dlen > 3 && strcmp(&dest[dlen-3], "/..") == 0)
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
/* find out what our safety margin is */
|
|
||||||
for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
|
|
||||||
/* ".." segment starts the count over. "." segment is ignored. */
|
|
@ -1,141 +0,0 @@
|
|||||||
diff --git a/checksum.c b/checksum.c
|
|
||||||
index cb21882..66e8089 100644
|
|
||||||
--- a/checksum.c
|
|
||||||
+++ b/checksum.c
|
|
||||||
@@ -406,7 +406,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
|
|
||||||
|
|
||||||
memset(sum, 0, MAX_DIGEST_LEN);
|
|
||||||
|
|
||||||
- fd = do_open(fname, O_RDONLY, 0);
|
|
||||||
+ fd = do_open_checklinks(fname);
|
|
||||||
if (fd == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
diff --git a/generator.c b/generator.c
|
|
||||||
index 110db28..3f13bb9 100644
|
|
||||||
--- a/generator.c
|
|
||||||
+++ b/generator.c
|
|
||||||
@@ -1867,7 +1867,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* open the file */
|
|
||||||
- if ((fd = do_open(fnamecmp, O_RDONLY, 0)) < 0) {
|
|
||||||
+ if ((fd = do_open_checklinks(fnamecmp)) < 0) {
|
|
||||||
rsyserr(FERROR, errno, "failed to open %s, continuing",
|
|
||||||
full_fname(fnamecmp));
|
|
||||||
pretend_missing:
|
|
||||||
diff --git a/receiver.c b/receiver.c
|
|
||||||
index 8031b8f..edfbb21 100644
|
|
||||||
--- a/receiver.c
|
|
||||||
+++ b/receiver.c
|
|
||||||
@@ -775,7 +775,7 @@ int recv_files(int f_in, int f_out, char *local_name)
|
|
||||||
if (fd1 == -1 && protocol_version < 29) {
|
|
||||||
if (fnamecmp != fname) {
|
|
||||||
fnamecmp = fname;
|
|
||||||
- fd1 = do_open(fnamecmp, O_RDONLY, 0);
|
|
||||||
+ fd1 = do_open_nofollow(fnamecmp, O_RDONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd1 == -1 && basis_dir[0]) {
|
|
||||||
diff --git a/sender.c b/sender.c
|
|
||||||
index 2bbff2f..a4d46c3 100644
|
|
||||||
--- a/sender.c
|
|
||||||
+++ b/sender.c
|
|
||||||
@@ -350,7 +350,7 @@ void send_files(int f_in, int f_out)
|
|
||||||
exit_cleanup(RERR_PROTOCOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
- fd = do_open(fname, O_RDONLY, 0);
|
|
||||||
+ fd = do_open_checklinks(fname);
|
|
||||||
if (fd == -1) {
|
|
||||||
if (errno == ENOENT) {
|
|
||||||
enum logcode c = am_daemon
|
|
||||||
diff --git a/syscall.c b/syscall.c
|
|
||||||
index 47c5ea5..c55ae5f 100644
|
|
||||||
--- a/syscall.c
|
|
||||||
+++ b/syscall.c
|
|
||||||
@@ -45,6 +45,8 @@ extern int preallocate_files;
|
|
||||||
extern int preallocate_files;
|
|
||||||
extern int preserve_perms;
|
|
||||||
extern int preserve_executability;
|
|
||||||
+extern int copy_links;
|
|
||||||
+extern int copy_unsafe_links;
|
|
||||||
|
|
||||||
#ifndef S_BLKSIZE
|
|
||||||
# if defined hpux || defined __hpux__ || defined __hpux
|
|
||||||
@@ -575,3 +575,21 @@ int do_open_nofollow(const char *pathname, int flags)
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ varient of do_open/do_open_nofollow which does do_open() if the
|
|
||||||
+ copy_links or copy_unsafe_links options are set and does
|
|
||||||
+ do_open_nofollow() otherwise
|
|
||||||
+
|
|
||||||
+ This is used to prevent a race condition where an attacker could be
|
|
||||||
+ switching a file between being a symlink and being a normal file
|
|
||||||
+
|
|
||||||
+ The open is always done with O_RDONLY flags
|
|
||||||
+ */
|
|
||||||
+int do_open_checklinks(const char *pathname)
|
|
||||||
+{
|
|
||||||
+ if (copy_links || copy_unsafe_links) {
|
|
||||||
+ return do_open(pathname, O_RDONLY, 0);
|
|
||||||
+ }
|
|
||||||
+ return do_open_nofollow(pathname, O_RDONLY);
|
|
||||||
+}
|
|
||||||
diff --git a/t_unsafe.c b/t_unsafe.c
|
|
||||||
index 010cac5..e10619a 100644
|
|
||||||
--- a/t_unsafe.c
|
|
||||||
+++ b/t_unsafe.c
|
|
||||||
@@ -28,6 +28,9 @@ int am_root = 0;
|
|
||||||
int human_readable = 0;
|
|
||||||
int preserve_perms = 0;
|
|
||||||
int preserve_executability = 0;
|
|
||||||
+int copy_links = 0;
|
|
||||||
+int copy_unsafe_links = 0;
|
|
||||||
+
|
|
||||||
short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG];
|
|
||||||
|
|
||||||
int
|
|
||||||
diff --git a/tls.c b/tls.c
|
|
||||||
index e6b0708..858f8f1 100644
|
|
||||||
--- a/tls.c
|
|
||||||
+++ b/tls.c
|
|
||||||
@@ -49,6 +49,9 @@ int list_only = 0;
|
|
||||||
int preserve_executability = 0;
|
|
||||||
int preallocate_files = 0;
|
|
||||||
int inplace = 0;
|
|
||||||
+int safe_symlinks = 0;
|
|
||||||
+int copy_links = 0;
|
|
||||||
+int copy_unsafe_links = 0;
|
|
||||||
|
|
||||||
#ifdef SUPPORT_XATTRS
|
|
||||||
|
|
||||||
diff --git a/trimslash.c b/trimslash.c
|
|
||||||
index 1ec928c..f2774cd 100644
|
|
||||||
--- a/trimslash.c
|
|
||||||
+++ b/trimslash.c
|
|
||||||
@@ -26,6 +26,8 @@ int am_root = 0;
|
|
||||||
int preserve_executability = 0;
|
|
||||||
int preallocate_files = 0;
|
|
||||||
int inplace = 0;
|
|
||||||
+int copy_links = 0;
|
|
||||||
+int copy_unsafe_links = 0;
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char **argv)
|
|
||||||
diff --git a/util.c b/util.c
|
|
||||||
index f260d39..d84bc41 100644
|
|
||||||
--- a/util.c
|
|
||||||
+++ b/util.c
|
|
||||||
@@ -365,7 +365,7 @@ int copy_file(const char *source, const char *dest, int tmpfilefd, mode_t mode)
|
|
||||||
int len; /* Number of bytes read into `buf'. */
|
|
||||||
OFF_T prealloc_len = 0, offset = 0;
|
|
||||||
|
|
||||||
- if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
|
|
||||||
+ if ((ifd = do_open_nofollow(source, O_RDONLY)) < 0) {
|
|
||||||
int save_errno = errno;
|
|
||||||
rsyserr(FERROR_XFER, errno, "open %s", full_fname(source));
|
|
||||||
errno = save_errno;
|
|
@ -1,54 +0,0 @@
|
|||||||
diff --git a/zlib/inftrees.c b/zlib/inftrees.c
|
|
||||||
index 44d89cf2..571e8100 100644
|
|
||||||
--- a/zlib/inftrees.c
|
|
||||||
+++ b/zlib/inftrees.c
|
|
||||||
@@ -54,7 +54,7 @@ unsigned short FAR *work;
|
|
||||||
code FAR *next; /* next available space in table */
|
|
||||||
const unsigned short FAR *base; /* base value table to use */
|
|
||||||
const unsigned short FAR *extra; /* extra bits table to use */
|
|
||||||
- int end; /* use base and extra for symbol > end */
|
|
||||||
+ unsigned match; /* use base and extra for symbol >= match */
|
|
||||||
unsigned short count[MAXBITS+1]; /* number of codes of each length */
|
|
||||||
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
|
|
||||||
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
|
|
||||||
@@ -181,19 +181,17 @@ unsigned short FAR *work;
|
|
||||||
switch (type) {
|
|
||||||
case CODES:
|
|
||||||
base = extra = work; /* dummy value--not used */
|
|
||||||
- end = 19;
|
|
||||||
+ match = 20;
|
|
||||||
break;
|
|
||||||
case LENS:
|
|
||||||
base = lbase;
|
|
||||||
- base -= 257;
|
|
||||||
extra = lext;
|
|
||||||
- extra -= 257;
|
|
||||||
- end = 256;
|
|
||||||
+ match = 257;
|
|
||||||
break;
|
|
||||||
default: /* DISTS */
|
|
||||||
base = dbase;
|
|
||||||
extra = dext;
|
|
||||||
- end = -1;
|
|
||||||
+ match = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize state for loop */
|
|
||||||
@@ -216,13 +214,13 @@ unsigned short FAR *work;
|
|
||||||
for (;;) {
|
|
||||||
/* create table entry */
|
|
||||||
here.bits = (unsigned char)(len - drop);
|
|
||||||
- if ((int)(work[sym]) < end) {
|
|
||||||
+ if (work[sym] + 1u < match) {
|
|
||||||
here.op = (unsigned char)0;
|
|
||||||
here.val = work[sym];
|
|
||||||
}
|
|
||||||
- else if ((int)(work[sym]) > end) {
|
|
||||||
- here.op = (unsigned char)(extra[work[sym]]);
|
|
||||||
- here.val = base[work[sym]];
|
|
||||||
+ else if (work[sym] >= match) {
|
|
||||||
+ here.op = (unsigned char)(extra[work[sym] - match]);
|
|
||||||
+ here.val = base[work[sym] - match];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
here.op = (unsigned char)(32 + 64); /* end of block */
|
|
@ -1,218 +0,0 @@
|
|||||||
diff --git a/exclude.c b/exclude.c
|
|
||||||
index d36a105e..da25661b 100644
|
|
||||||
--- a/exclude.c
|
|
||||||
+++ b/exclude.c
|
|
||||||
@@ -33,18 +33,15 @@ 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 read_batch;
|
|
||||||
-extern int list_only;
|
|
||||||
+extern int trust_sender_args;
|
|
||||||
extern int module_id;
|
|
||||||
|
|
||||||
-extern char *filesfrom_host;
|
|
||||||
extern char curr_dir[MAXPATHLEN];
|
|
||||||
extern unsigned int curr_dir_len;
|
|
||||||
extern unsigned int module_dirlen;
|
|
||||||
@@ -55,6 +52,7 @@ 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_args = 0;
|
|
||||||
int trust_sender_filter = 0;
|
|
||||||
|
|
||||||
/* Need room enough for ":MODS " prefix plus some room to grow. */
|
|
||||||
@@ -377,7 +375,7 @@ void add_implied_include(const char *arg, int skip_daemon_module)
|
|
||||||
int slash_cnt = 0;
|
|
||||||
const char *cp;
|
|
||||||
char *p;
|
|
||||||
- if (am_server || old_style_args || list_only || read_batch || filesfrom_host != NULL)
|
|
||||||
+ if (trust_sender_args)
|
|
||||||
return;
|
|
||||||
if (partial_string_len) {
|
|
||||||
arg_len = strlen(arg);
|
|
||||||
diff --git a/main.c b/main.c
|
|
||||||
index 6721ceb7..9ebfbea7 100644
|
|
||||||
--- a/main.c
|
|
||||||
+++ b/main.c
|
|
||||||
@@ -89,7 +89,6 @@ extern int backup_dir_len;
|
|
||||||
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;
|
|
||||||
@@ -636,7 +635,6 @@ 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/options.c b/options.c
|
|
||||||
index e7a9fcae..4feeb7e0 100644
|
|
||||||
--- a/options.c
|
|
||||||
+++ b/options.c
|
|
||||||
@@ -27,6 +27,8 @@
|
|
||||||
extern int local_server;
|
|
||||||
extern int sanitize_paths;
|
|
||||||
extern int daemon_over_rsh;
|
|
||||||
+extern int trust_sender_args;
|
|
||||||
+extern int trust_sender_filter;
|
|
||||||
extern unsigned int module_dirlen;
|
|
||||||
extern filter_rule_list filter_list;
|
|
||||||
extern filter_rule_list daemon_filter_list;
|
|
||||||
@@ -64,6 +66,7 @@ int preserve_atimes = 0;
|
|
||||||
static int daemon_opt; /* sets am_daemon after option error-reporting */
|
|
||||||
static int omit_dir_times = 0;
|
|
||||||
static int omit_link_times = 0;
|
|
||||||
+int trust_sender = 0;
|
|
||||||
static int F_option_cnt = 0;
|
|
||||||
static int modify_window_set;
|
|
||||||
static int itemize_changes = 0;
|
|
||||||
@@ -788,6 +791,7 @@ static struct poptOption long_options[] = {
|
|
||||||
{"protect-args", 's', POPT_ARG_VAL, &protect_args, 1, 0, 0},
|
|
||||||
{"no-protect-args", 0, POPT_ARG_VAL, &protect_args, 0, 0, 0},
|
|
||||||
{"no-s", 0, POPT_ARG_VAL, &protect_args, 0, 0, 0},
|
|
||||||
+ {"trust-sender", 0, POPT_ARG_VAL, &trust_sender, 1, 0, 0},
|
|
||||||
{"numeric-ids", 0, POPT_ARG_VAL, &numeric_ids, 1, 0, 0 },
|
|
||||||
{"no-numeric-ids", 0, POPT_ARG_VAL, &numeric_ids, 0, 0, 0 },
|
|
||||||
{"usermap", 0, POPT_ARG_STRING, 0, OPT_USERMAP, 0, 0 },
|
|
||||||
@@ -2465,6 +2469,11 @@ int parse_arguments(int *argc_p, const char ***argv_p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (trust_sender || am_server || read_batch)
|
|
||||||
+ trust_sender_args = trust_sender_filter = 1;
|
|
||||||
+ else if (old_style_args || filesfrom_host != NULL)
|
|
||||||
+ trust_sender_args = 1;
|
|
||||||
+
|
|
||||||
am_starting_up = 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
@@ -2438,9 +2438,7 @@ char *safe_arg(const char *opt, const char *arg)
|
|
||||||
char *ret;
|
|
||||||
if (!protect_args && old_style_args < 2 && (!old_style_args || (!is_filename_arg && opt != SPLIT_ARG_WHEN_OLD))) {
|
|
||||||
const char *f;
|
|
||||||
- if (!old_style_args && *arg == '~'
|
|
||||||
- && ((relative_paths && !strstr(arg, "/./"))
|
|
||||||
- || !strchr(arg, '/'))) {
|
|
||||||
+ if (!trust_sender_args && *arg == '~' && (relative_paths || !strchr(arg, '/'))) {
|
|
||||||
extras++;
|
|
||||||
escape_leading_tilde = 1;
|
|
||||||
}
|
|
||||||
diff --git a/rsync.1.old b/rsync.1
|
|
||||||
index 839f5ad..6882cf5 100644
|
|
||||||
--- a/rsync.1.old
|
|
||||||
+++ b/rsync.1
|
|
||||||
@@ -182,9 +182,39 @@ particular rsync daemon by leaving off the module name:
|
|
||||||
\f(CWrsync somehost.mydomain.com::\fP
|
|
||||||
.RE
|
|
||||||
|
|
||||||
-.PP
|
|
||||||
-See the following section for more details.
|
|
||||||
-.PP
|
|
||||||
+.SH "MULTI-HOST SECURITY"
|
|
||||||
+
|
|
||||||
+.PP
|
|
||||||
+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.
|
|
||||||
+.PP
|
|
||||||
+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, 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.
|
|
||||||
+.PP
|
|
||||||
+For those that don't yet have a 3.2.5 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:
|
|
||||||
+.PP
|
|
||||||
+.RS
|
|
||||||
+\f(CWrsync \-aiv host:dir1 ~\fP
|
|
||||||
+.RE
|
|
||||||
+.PP
|
|
||||||
+A safer command would be:
|
|
||||||
+.RS
|
|
||||||
+\f(CWrsync \-aiv host:dir1 ~/host-files\fP
|
|
||||||
+.RE
|
|
||||||
+.PP
|
|
||||||
+See the \fB\-\-trust\-sender\fP option for additional details.
|
|
||||||
+
|
|
||||||
.SH "ADVANCED USAGE"
|
|
||||||
|
|
||||||
.PP
|
|
||||||
@@ -519,6 +549,7 @@ to the detailed description below for a complete description.
|
|
||||||
\-0, \-\-from0 all *from/filter files are delimited by 0s
|
|
||||||
\-\-old\-args disable the modern arg-protection idiom
|
|
||||||
\-s, \-\-protect\-args no space\-splitting; wildcard chars only
|
|
||||||
+ \-\-trust\-sender trust the remote sender's file list
|
|
||||||
\-\-address=ADDRESS bind address for outgoing socket to daemon
|
|
||||||
\-\-port=PORT specify double\-colon alternate port number
|
|
||||||
\-\-sockopts=OPTIONS specify custom TCP options
|
|
||||||
@@ -2119,6 +2150,49 @@ This option conflicts with the \fB\-\-old\-args\fP option.
|
|
||||||
Note that this option is incompatible with the use of the restricted rsync
|
|
||||||
script (`rrsync`) since it hides options from the script's inspection.
|
|
||||||
.IP
|
|
||||||
+.IP "\fB\-\-trust\-sender\fP"
|
|
||||||
+This option disables two extra validation checks that a local client
|
|
||||||
+performs on the file list generated by a remote sender. This option should
|
|
||||||
+only be used if you trust the sender to not put something malicious in the
|
|
||||||
+file list (something that could possibly be done via a modified rsync, a
|
|
||||||
+modified shell, or some other similar manipulation).
|
|
||||||
+.IP
|
|
||||||
+Normally, the rsync client (as of version 3.2.5) runs two extra validation
|
|
||||||
+checks when pulling files from a remote rsync:
|
|
||||||
+.RS
|
|
||||||
+.IP o
|
|
||||||
+It verifies that additional arg items didn't get added at the top of the
|
|
||||||
+transfer.
|
|
||||||
+.IP o
|
|
||||||
+It verifies that none of the items in the file list are names that should
|
|
||||||
+have been excluded (if filter rules were specified).
|
|
||||||
+.RE
|
|
||||||
+.IP
|
|
||||||
+Note that various options can turn off one or both of these checks if the
|
|
||||||
+option interferes with the validation. For instance:
|
|
||||||
+.RS
|
|
||||||
+.IP o
|
|
||||||
+Using a per-directory filter file reads filter rules that only the server
|
|
||||||
+knows about, so the filter checking is disabled.
|
|
||||||
+.IP o
|
|
||||||
+Using the \fB\-\-old\-args\fP option allows the sender to manipulate the
|
|
||||||
+requested args, so the arg checking is disabled.
|
|
||||||
+.IP o
|
|
||||||
+Reading the files-from list from the server side means that the client
|
|
||||||
+doesn't know the arg list, so the arg checking is disabled.
|
|
||||||
+.IP o
|
|
||||||
+Using \fB\-\-read\-batch\fP disables both checks since the batch file's
|
|
||||||
+contents will have been verified when it was created.
|
|
||||||
+.RE
|
|
||||||
+.IP
|
|
||||||
+This option may help an under-powered client server if the extra pattern
|
|
||||||
+matching is slowing things down on a huge transfer. It can also be used
|
|
||||||
+work around a currently-unknown bug in the verification logic for a transfer
|
|
||||||
+from a trusted sender.
|
|
||||||
+.IP
|
|
||||||
+When using this option it is a good idea to specify a dedicated destination
|
|
||||||
+directory, as discussed in the \(dq\&MULTI-HOST SECURITY\(dq\& section.
|
|
||||||
+.IP
|
|
||||||
.IP "\fB\-T, \-\-temp\-dir=DIR\fP"
|
|
||||||
This option instructs rsync to use DIR as a
|
|
||||||
scratch directory when creating temporary copies of the files transferred
|
|
8
gating.yaml
Normal file
8
gating.yaml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
--- !Policy
|
||||||
|
product_versions:
|
||||||
|
- rhel-8
|
||||||
|
decision_context: osci_compose_gate
|
||||||
|
rules:
|
||||||
|
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
||||||
|
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}
|
||||||
|
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tedude.validation}
|
@ -9,7 +9,7 @@
|
|||||||
Summary: A program for synchronizing files over a network
|
Summary: A program for synchronizing files over a network
|
||||||
Name: rsync
|
Name: rsync
|
||||||
Version: 3.1.3
|
Version: 3.1.3
|
||||||
Release: 23%{?dist}
|
Release: 19%{?dist}.1
|
||||||
Group: Applications/Internet
|
Group: Applications/Internet
|
||||||
URL: http://rsync.samba.org/
|
URL: http://rsync.samba.org/
|
||||||
|
|
||||||
@ -42,13 +42,6 @@ Patch11: rsync-3.1.3-cve-2022-29154.patch
|
|||||||
Patch12: rsync-3.1.3-cve-2022-37434.patch
|
Patch12: rsync-3.1.3-cve-2022-37434.patch
|
||||||
Patch13: rsync-3.1.3-filtering-rules.patch
|
Patch13: rsync-3.1.3-filtering-rules.patch
|
||||||
Patch14: rsync-3.1.3-missing-xattr-filter.patch
|
Patch14: rsync-3.1.3-missing-xattr-filter.patch
|
||||||
Patch15: rsync-3.1.3-cve-2024-12085.patch
|
|
||||||
Patch16: rsync-3.1.3-cve-2024-12087.patch
|
|
||||||
Patch17: rsync-3.1.3-cve-2024-12088.patch
|
|
||||||
Patch18: rsync-3.1.3-cve-2024-12747.patch
|
|
||||||
# a fix for CVE-2016-9840 in zlib but marked as CVE-2025-4638 for a different component
|
|
||||||
Patch19: rsync-3.1.3-cve-2025-4638.patch
|
|
||||||
Patch20: rsync-3.1.3-trust-sender.patch
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Rsync uses a reliable algorithm to bring remote and host files into
|
Rsync uses a reliable algorithm to bring remote and host files into
|
||||||
@ -101,12 +94,6 @@ patch -p1 -i patches/copy-devices.diff
|
|||||||
%patch12 -p1 -b .cve-2022-37434
|
%patch12 -p1 -b .cve-2022-37434
|
||||||
%patch13 -p1 -b .filtering-rules
|
%patch13 -p1 -b .filtering-rules
|
||||||
%patch14 -p1 -b .xattr-filter
|
%patch14 -p1 -b .xattr-filter
|
||||||
%patch15 -p1 -b .cve-2024-12085
|
|
||||||
%patch16 -p1 -b .cve-2024-12087
|
|
||||||
%patch17 -p1 -b .cve-2024-12088
|
|
||||||
%patch18 -p1 -b .cve-2024-12747
|
|
||||||
%patch19 -p1 -b .cve-2025-4638
|
|
||||||
%patch20 -p1 -b .trust-sender
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%configure
|
%configure
|
||||||
@ -153,21 +140,6 @@ chmod -x support/*
|
|||||||
%systemd_postun_with_restart rsyncd.service
|
%systemd_postun_with_restart rsyncd.service
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Wed May 28 2025 Michal Ruprich <mruprich@redhat.com> - 3.1.3-23
|
|
||||||
- Resolves: RHEL-52004 - Slowness in rsync due to extra validation steps
|
|
||||||
|
|
||||||
* Mon May 26 2025 Michal Ruprich <mruprich@redhat.com> - 3.1.3-22
|
|
||||||
- Resolves: RHEL-91519 - Improper Pointer Arithmetic in pcl
|
|
||||||
|
|
||||||
* Tue Feb 04 2025 Michal Ruprich <mruprich@redhat.com> - 3.1.3-21
|
|
||||||
- Resolves: RHEL-70207 - Path traversal vulnerability in rsync
|
|
||||||
|
|
||||||
* Mon Feb 03 2025 Michal Ruprich <mruprich@redhat.com> - 3.1.3-20
|
|
||||||
- Resolves: RHEL-70207 - Path traversal vulnerability in rsync
|
|
||||||
- Resolves: RHEL-70209 - --safe-links option bypass leads to path traversal
|
|
||||||
- Resolves: RHEL-72502 - Race Condition in rsync Handling Symbolic Links
|
|
||||||
- Resolves: RHEL-70157 - Info Leak via Uninitialized Stack Contents
|
|
||||||
|
|
||||||
* Wed Nov 02 2022 Michal Ruprich <mruprich@redhat.com> - 3.1.3-19.1
|
* Wed Nov 02 2022 Michal Ruprich <mruprich@redhat.com> - 3.1.3-19.1
|
||||||
- Resolves: #2139118 - rsync-daemon fail on 3.1.3
|
- Resolves: #2139118 - rsync-daemon fail on 3.1.3
|
||||||
|
|
2
sources
Normal file
2
sources
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
SHA512 (rsync-3.1.3.tar.gz) = 8385f4c0ea37e7a1da3cf45794154f5bc4d1c49bc625ba3b5f85adaf3eafe6d71c15bdcb1410bde731e5d4c19aff3331606637462fa27a68dc3e13192dd78f99
|
||||||
|
SHA512 (rsync-patches-3.1.3.tar.gz) = eb0762faa8a2c170986e7e94a75f5dbe8fdb86b980bacc60e92df2c60e6340fdafa5256d67284d52ac32e097663c596533007db91d2b3ec6088a381cb229dc9f
|
Loading…
Reference in New Issue
Block a user