Funny issue with chroot + symlink outside chroot

Olivier Thauvin nanardon at nanardon.zarb.org
Sat Nov 10 17:36:03 GMT 2007


Hi,

The problem I found is not in what rsync, but on the error handling:

How to reproduce:
On server side I setup a tree and share using rsync + xinetd, of course, for 
security reason I use chroot option.

Now I push this symlink:
lrwxrwxrwx 1 root     root      4 nov 10 16:28 horsroot -> /bin/

Now I try to do:
./rsync -avPH  --copy-unsafe-links draco::test/ /tmp/rsyncdest/

(Of course the transfert will failed because /bin is outside the chroot.)

The first problem is the error message is not push to stderr but stdout:
---------------------------
[nanardon at draco rsync]$ rsync -avPH  --copy-unsafe-links 
virgo::test/ /tmp/rsyncdest/ 2>/dev/null
[...]
file has vanished: "/horsroot" (in test)
--------------------------

Nothing is sent to stderr whereas error code is set:
$ echo $?
24

I had a look to flist.c/sender.c, it seems this is expected behavior:
(flist.c:1037)
enum logcode c = am_daemon && protocol_version < 28
                    ? FERROR : FINFO;
and indeed the message is produce by daemon, and I am using proto 29 or 30.

Well, I also found the message is not the appropriate one, the file has not 
vanished (at least, we cannot know that, the file pointed is outside our 
tree).

I tried this to fix, but this part is not trivial, and I am not sure this does 
not have side effect. (The patch is partial, the same should be applied to 
sender.c).

diff -u -b -B -w -p -r1.468 flist.c
--- flist.c     6 Nov 2007 15:25:02 -0000       1.468
+++ flist.c     10 Nov 2007 17:21:51 -0000
@@ -1026,8 +1026,8 @@ struct file_struct *make_file(const char
                if (save_errno == ENOENT) {
 #ifdef SUPPORT_LINKS
                        /* Avoid "vanished" error if symlink points nowhere. 
*/
-                       if (copy_links && x_lstat(thisname, &st, NULL) == 0
-                           && S_ISLNK(st.st_mode)) {
+                       if ((copy_links && x_lstat(thisname, &st, NULL) == 0
+                           && S_ISLNK(st.st_mode)) || x_stat(thisname, &st, 
NULL) != 0) {
                                io_error |= IOERR_GENERAL;
                                rprintf(FERROR, "symlink has no 
referent: %s\n",
                                        full_fname(thisname));

Summary:
- should "vanished" message be report as INFO instead ERROR ?
- can we detected --copy-unsafe-symlink for file outside chroot ?

Regards.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url : http://lists.samba.org/archive/rsync/attachments/20071110/2c5aef7b/attachment.bin


More information about the rsync mailing list