Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:yukoff:openSUSE:Leap:42.1:Backports
rsync
0001-Receiver-now-rejects-invalid-filenames-in-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Receiver-now-rejects-invalid-filenames-in-filelist.patch of Package rsync
From 4cad402ea8a91031f86c53961d78bb7f4f174790 Mon Sep 17 00:00:00 2001 From: Wayne Davison <wayned@samba.org> Date: Sun, 13 Apr 2014 10:36:59 -0700 Subject: [PATCH] Receiver now rejects invalid filenames in filelist. If the receiver gets a filename with a leading slash (w/o --relative) and/or a filename with an embedded ".." dir in the path, it dies with an error (rather than continuing). Those invalid paths should never happen in reality, so just reject someone trying to pull a fast one. --- flist.c | 14 ++++++++------ rsync.h | 1 + util.c | 14 ++++++++++---- 3 files changed, 19 insertions(+), 10 deletions(-) Index: rsync-3.1.0/flist.c =================================================================== --- rsync-3.1.0.orig/flist.c 2016-01-07 13:10:13.395073933 +0100 +++ rsync-3.1.0/flist.c 2016-01-07 13:19:31.176074394 +0100 @@ -747,8 +747,11 @@ static struct file_struct *recv_file_ent } #endif - if (*thisname) - clean_fname(thisname, 0); + if (*thisname + && (clean_fname(thisname, CFN_REFUSE_DOT_DOT_DIRS) < 0 || (!relative_paths && *thisname == '/'))) { + rprintf(FERROR, "ABORTING due to unsafe pathname from sender: %s\n", thisname); + exit_cleanup(RERR_PROTOCOL); + } if (sanitize_paths) sanitize_path(thisname, thisname, "", 0, SP_DEFAULT); @@ -2564,6 +2567,9 @@ struct file_list *recv_file_list(int f) rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i()); } + /* The --relative option sends paths with a leading slash, so we need ++ * to specify the strip_root option here. We rejected leading slashes ++ * for a non-relative transfer in recv_file_entry(). */ flist_sort_and_clean(flist, relative_paths); if (protocol_version < 30) { Index: rsync-3.1.0/rsync.h =================================================================== --- rsync-3.1.0.orig/rsync.h 2016-01-07 13:10:13.396073949 +0100 +++ rsync-3.1.0/rsync.h 2016-01-07 13:10:14.189086604 +0100 @@ -208,6 +208,7 @@ #define CFN_KEEP_TRAILING_SLASH (1<<1) #define CFN_DROP_TRAILING_DOT_DIR (1<<2) #define CFN_COLLAPSE_DOT_DOT_DIRS (1<<3) +#define CFN_REFUSE_DOT_DOT_DIRS (1<<4) #define SP_DEFAULT 0 #define SP_KEEP_DOT_DIRS (1<<0) Index: rsync-3.1.0/util.c =================================================================== --- rsync-3.1.0.orig/util.c 2016-01-07 13:10:13.397073965 +0100 +++ rsync-3.1.0/util.c 2016-01-07 13:10:14.189086604 +0100 @@ -858,7 +858,7 @@ int count_dir_elements(const char *p) * CFN_KEEP_TRAILING_SLASH is flagged, and will also collapse ".." elements * (except at the start) if CFN_COLLAPSE_DOT_DOT_DIRS is flagged. If the * resulting name would be empty, returns ".". */ -unsigned int clean_fname(char *name, int flags) +int clean_fname(char *name, int flags) { char *limit = name - 1, *t = name, *f = name; int anchored; @@ -866,6 +866,8 @@ unsigned int clean_fname(char *name, int if (!name) return 0; +#define DOT_IS_DOT_DOT_DIR(bp) (bp[1] == '.' && (bp[2] == '/' || !bp[2])) + if ((anchored = *f == '/') != 0) { *t++ = *f++; #ifdef __CYGWIN__ @@ -878,7 +880,8 @@ unsigned int clean_fname(char *name, int } else if (flags & CFN_KEEP_DOT_DIRS && *f == '.' && f[1] == '/') { *t++ = *f++; *t++ = *f++; - } + } else if (flags & CFN_REFUSE_DOT_DOT_DIRS && *f == '.' && DOT_IS_DOT_DOT_DIR(f)) + return -1; while (*f) { /* discard extra slashes */ if (*f == '/') { @@ -894,9 +897,10 @@ unsigned int clean_fname(char *name, int if (f[1] == '\0' && flags & CFN_DROP_TRAILING_DOT_DIR) break; /* collapse ".." dirs */ - if (flags & CFN_COLLAPSE_DOT_DOT_DIRS - && f[1] == '.' && (f[2] == '/' || !f[2])) { + if (flags & (CFN_COLLAPSE_DOT_DOT_DIRS|CFN_REFUSE_DOT_DOT_DIRS) && DOT_IS_DOT_DOT_DIR(f)) { char *s = t - 1; + if (flags & CFN_REFUSE_DOT_DOT_DIRS) + return -1; if (s == name && anchored) { f += 2; continue; @@ -919,6 +923,8 @@ unsigned int clean_fname(char *name, int *t++ = '.'; *t = '\0'; +#undef DOT_IS_DOT_DOT_DIR + return t - name; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor