Bug 13364 - rsyncd clips trims relative symlinks outside of source tree
Summary: rsyncd clips trims relative symlinks outside of source tree
Status: RESOLVED WORKSFORME
Alias: None
Product: rsync
Classification: Unclassified
Component: core (show other bugs)
Version: 3.1.3
Hardware: x64 Linux
: P5 normal (vote)
Target Milestone: ---
Assignee: Wayne Davison
QA Contact: Rsync QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-04-02 03:36 UTC by Chris Severance
Modified: 2020-06-13 16:45 UTC (History)
0 users

See Also:


Attachments
setup instructions and copier (1.64 KB, application/x-shellscript)
2018-04-02 03:36 UTC, Chris Severance
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Severance 2018-04-02 03:36:25 UTC
Created attachment 14099 [details]
setup instructions and copier

A relative symlink that points outside the source tree is copied properly when copying server -> client. When copying client -> server leading '../' are trimmed until it fits in the source tree.

I need symlinks outside the source tree to not be trimmed copying in either direction.
Comment 1 Dave Gordon 2018-04-04 16:30:41 UTC
Comment on attachment 14099 [details]
setup instructions and copier

This is a documented feature; see rsyncd.conf(5):

  munge_symlinks
    ...
    When this parameter is disabled on a writable module and "use chroot" is
    off (or the inside-chroot path is not "/"), incoming symlinks will be
    modified to drop a leading slash and to remove ".." path elements that
    rsync believes will allow a symlink to escape the module’s hierarchy.
    There are tricky ways to work around this, though, so you had better
    trust your users if you choose this combination of parameters.

Unless you want the symlinks to be usable on the server as well as the client, why not enable munge-symlinks. That way the client will get back the same out-of-tree symlink as it started with, even though it will have had a different content while on the server.

.Dave.
Comment 2 Dave Gordon 2018-04-04 16:43:02 UTC
Comment on attachment 14099 [details]
setup instructions and copier

Having set up an rsync daemon (on localhost:10873):

$ # Initial fetch of daemon's directory:
$ rsync -ii -av rsync://localhost:10873/testrsync/ testrsync/
receiving incremental file list
.d..t...... ./
cL+++++++++ foo -> ../foo
sent 30 bytes  received 91 bytes  242.00 bytes/sec
total size is 6  speedup is 0.05
$ ls -lRa rsyncd/testrsync/ testrsync/
rsyncd/testrsync/:
total 4
drwxr-xr-x 1 dg32768 users  6 Apr  4 16:25 ./
drwxr-xr-x 1 dg32768 users 80 Apr  4 16:59 ../
lrwxrwxrwx 1 dg32768 users  6 Apr  4 16:15 foo -> ../foo

testrsync/:
total 4
drwxr-xr-x 1 dg32768 users    6 Apr  4 16:25 ./
drwxr-xr-x 1 dg32768 users 1846 Apr  4 16:58 ../
lrwxrwxrwx 1 dg32768 users    6 Apr  4 16:15 foo -> ../foo

$ # Refetch the same data:
$ strace -e trace=symlink rsync -ii -av rsync://localhost:10873/testrsync/ testrsync/
receiving incremental file list
.d          ./
.L          foo -> ../foo
sent 30 bytes  received 91 bytes  242.00 bytes/sec
total size is 6  speedup is 0.05
$ # Here the rsync itemisation shows that it *examined* the symlink but
$ # did *not* recreate it -- note that strace shows no symlink(2) calls.
$ # So no bug here either :)

.Dave.
Comment 3 Chris Severance 2018-04-04 19:52:20 UTC
>enable munge-symlinks. That way the client will get back the same out-of-tree symlink as it started with

This is a lousy option for backups. The only way to get my original links back is to pull the restore through rsync. Restoring directly from the rsyncd server will copy the munged links.

>Unless you want the symlinks to be usable on the server

This is exactly what is required. It's not a server at all. It's two clients both of which must have the same usable tree, one of which runs rsyncd to accept updates from the other.

I tried enabling chroot and the leading path was still clipped client->server.

>There are tricky ways to work around this

This is what I'm looking for. There should be no security for --links since copying links can never reach outside the server tree. --copy-links and --copy-unsafe-links could reach outside the tree so need to be limited whether or not the unsafe link was from the client.

I can build the links on both clients so --safe-links could work but I need a way to silence the warnings out of the -v listing.

Shortening the rsyncd "path=" so that the links become inside the tree could work but rsync has no usable way to specify only one directory without causing the links to be considered outside outside the tree.

cd baz2; rsync ./ rsync://.../baz1/ # original case

rsync bar2/ rsync://.../root/bar1/ # shortened path=

Links going to bar1 accessible by /root/ are considered outside of the bar1 tree and clipped.
Comment 4 Wayne Davison 2020-06-13 16:45:28 UTC
As long as "munge symlinks = false" is set for your module (which is the default with "use chroot = true" and a normal path value is set), then rsync doesn't tweak the symlinks in the transfer at all.