Hi,

I saw a DSA for CVE-2017-17433 so I looked it up

> The recv_files function in receiver.c in the daemon in rsync 3.1.2,
> and 3.1.3-development before 2017-12-03, proceeds with certain file
> metadata updates before checking for a filename in the
> daemon_filter_list data structure, which allows remote attackers to
> bypass intended access restrictions.

https://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-17433.html

I went then for the link patch
https://git.samba.org/?p=rsync.git;a=commit;h=3e06d40029cfdce9d0f73d87cfd4edaf54be9c51
but running make test before said
----- overall results:
      30 passed
      9 skipped
and after
----- overall results:
      27 passed
      3 failed
      9 skipped

I looked at the git history and saw some scary commits messages (like
"Enforce trailing \0 when receiving xattr name values") but I didn't
know what to backport. So I decided to look at what Debian did
https://sources.debian.org/src/rsync/3.1.2-2.1/debian/patches/

They backported that scary commit plus the commit said to fix the
CVE and the next commits on the same file, and that looks pretty
consistent to me.

Sadly, the result of 'make test' didn't change, so I also backported the
last commit which said it fixed the tests. Indeed it does.


Here's the diff. I think it should be rather straightforward (rsync
doesn't get updates every day) to apply on -stable and probably even on
-oldstable. Considering the importance of this package I think it would
be good to do it on the both. I'll look at them once current has been
dealt with.

Opinions from people who actually understand all these patches are
welcome. And ok too ;)

Cheers,
Daniel

Index: Makefile
===================================================================
RCS file: /cvs/ports/net/rsync/Makefile,v
retrieving revision 1.77
diff -u -p -r1.77 Makefile
--- Makefile    6 Apr 2016 21:17:29 -0000       1.77
+++ Makefile    18 Dec 2017 02:05:48 -0000
@@ -3,7 +3,7 @@
 COMMENT =      mirroring/synchronization over low bandwidth links
 
 DISTNAME =     rsync-3.1.2
-REVISION =     0
+REVISION =     1
 CATEGORIES =   net
 HOMEPAGE =     https://rsync.samba.org/
 
Index: patches/patch-receiver_c
===================================================================
RCS file: patches/patch-receiver_c
diff -N patches/patch-receiver_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-receiver_c    18 Dec 2017 02:05:48 -0000
@@ -0,0 +1,45 @@
+$OpenBSD$
+
+Backport from upstream
+3e06d40029cfdce9d0f73d87cfd4edaf54be9c51
+5509597decdbd7b91994210f700329d8a35e70a1
+f5e8a17e093065fb20fea00a29540fe2c7896441
+
+Index: receiver.c
+--- receiver.c.orig
++++ receiver.c
+@@ -583,6 +583,12 @@ int recv_files(int f_in, int f_out, char *local_name)
+               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);
++              }
++
+ #ifdef SUPPORT_XATTRS
+               if (preserve_xattrs && iflags & ITEM_REPORT_XATTR && do_xfers
+                && !(want_xattr_optim && BITS_SET(iflags, 
ITEM_XNAME_FOLLOWS|ITEM_LOCAL_CHANGE)))
+@@ -651,12 +657,6 @@ int recv_files(int f_in, int f_out, char *local_name)
+ 
+               cleanup_got_literal = 0;
+ 
+-              if (daemon_filter_list.head
+-                  && check_filter(&daemon_filter_list, FLOG, fname, 0) < 0) {
+-                      rprintf(FERROR, "attempt to hack rsync failed.\n");
+-                      exit_cleanup(RERR_PROTOCOL);
+-              }
+-
+               if (read_batch) {
+                       int wanted = redoing
+                                  ? we_want_redo(ndx)
+@@ -728,7 +728,7 @@ int recv_files(int f_in, int f_out, char *local_name)
+                               break;
+                       }
+                       if (!fnamecmp || (daemon_filter_list.head
+-                        && check_filter(&daemon_filter_list, FLOG, fname, 0) 
< 0)) {
++                        && check_filter(&daemon_filter_list, FLOG, fnamecmp, 
0) < 0)) {
+                               fnamecmp = fname;
+                               fnamecmp_type = FNAMECMP_FNAME;
+                       }
Index: patches/patch-rsync_c
===================================================================
RCS file: patches/patch-rsync_c
diff -N patches/patch-rsync_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-rsync_c       18 Dec 2017 02:05:48 -0000
@@ -0,0 +1,28 @@
+$OpenBSD$
+
+Backport from upstream
+70aeb5fddd1b2f8e143276f8d5a085db16c593b9
+
+Index: rsync.c
+--- rsync.c.orig
++++ rsync.c
+@@ -49,6 +49,7 @@ extern int flist_eof;
+ extern int file_old_total;
+ extern int keep_dirlinks;
+ extern int make_backups;
++extern int sanitize_paths;
+ extern struct file_list *cur_flist, *first_flist, *dir_flist;
+ extern struct chmod_mode_struct *daemon_chmod_modes;
+ #ifdef ICONV_OPTION
+@@ -396,6 +397,11 @@ int read_ndx_and_attrs(int f_in, int f_out, int *iflag
+       if (iflags & ITEM_XNAME_FOLLOWS) {
+               if ((len = read_vstring(f_in, buf, MAXPATHLEN)) < 0)
+                       exit_cleanup(RERR_PROTOCOL);
++
++              if (sanitize_paths) {
++                      sanitize_path(buf, buf, "", 0, SP_DEFAULT);
++                      len = strlen(buf);
++              }
+       } else {
+               *buf = '\0';
+               len = -1;
Index: patches/patch-xattrs_c
===================================================================
RCS file: patches/patch-xattrs_c
diff -N patches/patch-xattrs_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-xattrs_c      18 Dec 2017 02:05:48 -0000
@@ -0,0 +1,19 @@
+$OpenBSD$
+
+Backport from upstream
+47a63d90e71d3e19e0e96052bb8c6b9cb140ecc1
+
+Index: xattrs.c
+--- xattrs.c.orig
++++ xattrs.c
+@@ -696,6 +696,10 @@ void receive_xattr(int f, struct file_struct *file)
+                       out_of_memory("receive_xattr");
+               name = ptr + dget_len + extra_len;
+               read_buf(f, name, name_len);
++              if (name_len < 1 || name[name_len-1] != '\0') {
++                      rprintf(FERROR, "Invalid xattr name received (missing 
trailing \\0).\n");
++                      exit_cleanup(RERR_FILEIO);
++              }
+               if (dget_len == datum_len)
+                       read_buf(f, ptr, dget_len);
+               else {

Reply via email to