File rsync-CVE-2011-1097.patch of Package rsync

--- flist.c.orig	2011-04-04 13:46:48.804602022 +0200
+++ flist.c	2011-04-04 13:51:02.715517695 +0200
@@ -52,12 +52,9 @@ extern int preserve_links;
 extern int preserve_hard_links;
 extern int preserve_devices;
 extern int preserve_specials;
-extern int uid_ndx;
-extern int gid_ndx;
 extern int eol_nulls;
 extern int relative_paths;
 extern int implied_dirs;
-extern int file_extra_cnt;
 extern int ignore_perishable;
 extern int non_perishable_cnt;
 extern int prune_empty_dirs;
@@ -69,6 +66,7 @@ extern int munge_symlinks;
 extern int need_unsorted_flist;
 extern int sender_symlink_iconv;
 extern int unsort_ndx;
+extern uid_t our_uid;
 extern struct stats stats;
 extern char *filesfrom_host;
 
@@ -1273,13 +1271,15 @@ struct file_struct *make_file(const char
 	}
 #endif
 	file->mode = st.st_mode;
-	if (uid_ndx) /* Check uid_ndx instead of preserve_uid for del support */
+	if (preserve_uid)
 		F_OWNER(file) = st.st_uid;
-	if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
+	if (preserve_gid)
 		F_GROUP(file) = st.st_gid;
 
 	if (basename != thisname)
 		file->dirname = lastdir;
+        if (am_generator && st.st_uid == our_uid)
+                file->flags |= FLAG_OWNED_BY_US;
 
 #ifdef SUPPORT_LINKS
 	if (linkname_len)
@@ -2957,13 +2957,14 @@ char *f_name(const struct file_struct *f
  * of the dirname string, and also indicates that "dirname" is a MAXPATHLEN
  * buffer (the functions we call will append names onto the end, but the old
  * dir value will be restored on exit). */
-struct file_list *get_dirlist(char *dirname, int dlen, int ignore_filter_rules)
+struct file_list *get_dirlist(char *dirname, int dlen, int flags)
 {
 	struct file_list *dirlist;
 	char dirbuf[MAXPATHLEN];
 	int save_recurse = recurse;
 	int save_xfer_dirs = xfer_dirs;
 	int save_prune_empty_dirs = prune_empty_dirs;
+        int senddir_fd = flags & GDL_IGNORE_FILTER_RULES ? -2 : -1;
 
 	if (dlen < 0) {
 		dlen = strlcpy(dirbuf, dirname, MAXPATHLEN);
@@ -2976,7 +2977,7 @@ struct file_list *get_dirlist(char *dirn
 
 	recurse = 0;
 	xfer_dirs = 1;
-	send_directory(ignore_filter_rules ? -2 : -1, dirlist, dirname, dlen, 0);
+        send_directory(senddir_fd, dirlist, dirname, dlen, FLAG_CONTENT_DIR);
 	xfer_dirs = save_xfer_dirs;
 	recurse = save_recurse;
 	if (do_progress)
--- generator.c.orig	2011-04-04 13:47:06.300683596 +0200
+++ generator.c	2011-04-04 13:54:30.368444402 +0200
@@ -44,8 +44,6 @@ extern int preserve_hard_links;
 extern int preserve_executability;
 extern int preserve_perms;
 extern int preserve_times;
-extern int uid_ndx;
-extern int gid_ndx;
 extern int delete_mode;
 extern int delete_before;
 extern int delete_during;
@@ -169,19 +167,12 @@ static enum delret delete_item(char *fbu
 		do_chmod(fbuf, mode | S_IWUSR);
 
 	if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
-		int save_uid_ndx = uid_ndx;
 		/* This only happens on the first call to delete_item() since
 		 * delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
-		if (!uid_ndx)
-			uid_ndx = ++file_extra_cnt;
 		ignore_perishable = 1;
 		/* If DEL_RECURSE is not set, this just reports emptiness. */
 		ret = delete_dir_contents(fbuf, flags);
 		ignore_perishable = 0;
-		if (!save_uid_ndx) {
-			--file_extra_cnt;
-			uid_ndx = 0;
-		}
 		if (ret == DR_NOT_EMPTY || ret == DR_AT_LIMIT)
 			goto check_ret;
 		/* OK: try to delete the directory. */
@@ -294,7 +285,7 @@ static enum delret delete_dir_contents(c
 		}
 
 		strlcpy(p, fp->basename, remainder);
-		if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
+                if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
 			do_chmod(fname, fp->mode | S_IWUSR);
 		/* Save stack by recursing to ourself directly. */
 		if (S_ISDIR(fp->mode)) {
@@ -472,7 +463,6 @@ static void delete_in_dir(char *fbuf, st
 	struct file_list *dirlist;
 	char delbuf[MAXPATHLEN];
 	int dlen, i;
-	int save_uid_ndx = uid_ndx;
 
 	if (!fbuf) {
 		change_local_filter_dir(NULL, 0, 0);
@@ -504,9 +494,6 @@ static void delete_in_dir(char *fbuf, st
 			return;
 	}
 
-	if (!uid_ndx)
-		uid_ndx = ++file_extra_cnt;
-
 	dirlist = get_dirlist(fbuf, dlen, 0);
 
 	/* If an item in dirlist is not found in flist, delete it
@@ -523,7 +510,7 @@ static void delete_in_dir(char *fbuf, st
 		}
 		if (flist_find(cur_flist, fp) < 0) {
 			int flags = DEL_RECURSE;
-			if (!(fp->mode & S_IWUSR) && !am_root && (uid_t)F_OWNER(fp) == our_uid)
+                        if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US)
 				flags |= DEL_NO_UID_WRITE;
 			f_name(fp, delbuf);
 			if (delete_during == 2) {
@@ -535,11 +522,6 @@ static void delete_in_dir(char *fbuf, st
 	}
 
 	flist_free(dirlist);
-
-	if (!save_uid_ndx) {
-		--file_extra_cnt;
-		uid_ndx = 0;
-	}
 }
 
 /* This deletes any files on the receiving side that are not present on the
@@ -1358,7 +1340,7 @@ static void recv_generator(char *fname,
 
 		if (need_fuzzy_dirlist && S_ISREG(file->mode)) {
 			strlcpy(fnamecmpbuf, dn, sizeof fnamecmpbuf);
-			fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, 1);
+                        fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, GDL_IGNORE_FILTER_RULES);
 			need_fuzzy_dirlist = 0;
 		}
 
--- log.c.orig	2011-04-04 13:47:10.729683488 +0200
+++ log.c	2011-04-04 13:54:43.529444053 +0200
@@ -35,8 +35,6 @@ extern int msg_fd_out;
 extern int allow_8bit_chars;
 extern int protocol_version;
 extern int preserve_times;
-extern int uid_ndx;
-extern int gid_ndx;
 extern int progress_is_active;
 extern int stdout_format_has_i;
 extern int stdout_format_has_o_or_i;
--- rsync.c.orig	2011-04-04 13:47:19.036435159 +0200
+++ rsync.c	2011-04-04 13:54:53.415611780 +0200
@@ -41,8 +41,6 @@ extern int am_generator;
 extern int am_starting_up;
 extern int allow_8bit_chars;
 extern int protocol_version;
-extern int uid_ndx;
-extern int gid_ndx;
 extern int inc_recurse;
 extern int inplace;
 extern int flist_eof;
--- rsync.h.orig	2011-04-04 13:47:26.561693743 +0200
+++ rsync.h	2011-04-04 13:55:56.525445308 +0200
@@ -64,6 +64,7 @@
 /* These flags are used in the live flist data. */
 
 #define FLAG_TOP_DIR (1<<0)	/* sender/receiver/generator */
+#define FLAG_OWNED_BY_US (1<<0) /* generator: set by make_file() for aux flists only */
 #define FLAG_FILE_SENT (1<<1)	/* sender/receiver/generator */
 #define FLAG_DIR_CREATED (1<<1)	/* generator */
 #define FLAG_CONTENT_DIR (1<<2)	/* sender/receiver/generator */
@@ -84,6 +85,10 @@
 
 #define FLAG_DIVERT_DIRS (1<<16)/* sender */
 
+/* These flags are for get_dirlist(). */
+#define GDL_IGNORE_FILTER_RULES (1<<0)
+
+/* Some helper macros for matching bits. */
 #define BITS_SET(val,bits) (((val) & (bits)) == (bits))
 #define BITS_SETnUNSET(val,onbits,offbits) (((val) & ((onbits)|(offbits))) == (onbits))
 #define BITS_EQUAL(b1,b2,mask) (((unsigned)(b1) & (unsigned)(mask)) \