Unfortunate results from fake-super
Dave Gordon
dg32768 at zoho.eu
Sat Feb 3 17:44:47 UTC 2018
On 03/02/18 15:52, Dave Gordon via rsync wrote:
> On 03/02/18 13:20, Dave Gordon via rsync wrote:
>> When using fake-super mode in an rsync receiver, anything that's neither a
>> file nor a directory (e.g. devices, symlinks, etc) is converted into a file,
>> and properties such as original ownership, filetype, and permissions are
>> stored in a specific extended attribute.
>>
>> In the case of a symlink, the contents of the link are stored in a plain
>> file. The original mode of the symlink is normally irrelevant, because
>> (Linux) hosts ignore a symlink's mode and use that of the target instead.
>> But in fake-super mode, the original mode of the link itself (usually
>> 0120777) is used to set the permissions on the receiver's plain-file copy.
>>
>> This results in the copy being world-writable. If this plain file is altered
>> and then transferred back to the origin, the resulting symlink can point to
>> an arbitrary path, which leads to potential security issues.
>>
>> Example:
>>
>> This was first observed in version 3.1.1 on kubuntu, but is still the same
>> in version 3.1.3 as of 28 Jan 2018.
>> See also Storing-ownership-device-nodes-without-root
>> <http://samba.2283325.n4.nabble.com/Storing-ownership-device-nodes-without-root-td2503256.html#a2503261>
>>
>> .Dave.
>>
>> --
>> Sent from: http://samba.2283325.n4.nabble.com/Samba-rsync-f2500462.html
>>
>
> Hmm, the forum seems to have dropped the example (which was in 'raw'
> tags to preserve the formatting). Oh well, here it is ...
>
> Example:
>
> As regular user 'dg':
> dg$ mkdir src
> dg$ touch src/foo
> dg$ chmod 444 src/foo
> dg$ ln -s foo src/bar
>
> Then as trusted (but unprivileged) user 'backup':
> backup$ id -a
> uid=1000(backup) gid=1000(backup) groups=1000(backup),100(users)
> backup$ umask
> 0022
> backup$ rsync -av src/ dst-nonsuper/
> backup$ rsync -av --fake-super src/ dst-fake-super/
>
> Now as (untrusted) user 'guest':
> guest$ id -a
> uid=9999(guest) gid=9999(guest) groups=9999(guest)
> guest$ echo -n '/etc/shadow' > dst-nonsuper/bar
> bash: dst-nonsuper/bar: Permission denied
> guest$ echo -n '/etc/secret' > dst-fake-super/bar # allowed!!
>
> And finally, as user 'dg', restore from the fake-super backup:
> dg$ rsync -av --fake-super -M--super dst-fake-super/ recovered/
> dg$ ls -laR */
> ./src:
> total 8
> drwxr-xr-x 2 dg users 4096 Feb 3 11:59 .
> drwxrwxr-x 6 dg users 4096 Feb 3 13:00 ..
> lrwxrwxrwx 1 dg users 3 Feb 3 11:59 bar -> foo
> -r--r--r-- 1 dg users 0 Feb 3 11:59 foo
>
> ./dst-nonsuper:
> total 8
> drwxr-xr-x 2 backup users 4096 Feb 3 11:59 .
> drwxrwxr-x 6 dg users 4096 Feb 3 13:00 ..
> lrwxrwxrwx 1 backup users 3 Feb 3 11:59 bar -> foo
> -r--r--r-- 1 backup users 0 Feb 3 11:59 foo
>
> ./dst-fake-super:
> total 12
> drwxr-xr-x 2 backup backup 4096 Feb 3 11:59 .
> drwxrwxr-x 6 dg users 4096 Feb 3 13:00 ..
> -rwxrwxrwx 1 backup backup 11 Feb 3 12:51 bar
> -rw-r--r-- 1 backup backup 0 Feb 3 11:59 foo
>
> ./recovered:
> total 8
> drwxr-xr-x 2 dg users 4096 Feb 3 11:59 .
> drwxrwxr-x 6 dg users 4096 Feb 3 13:00 ..
> lrwxrwxrwx 1 dg users 11 Feb 3 12:51 bar -> /etc/secret
> -r--r--r-- 1 dg users 0 Feb 3 11:59 foo
>
> dg$ getfattr -d -R */
>
> # file: dst-fake-super
> user.rsync.%stat="40755 0,0 32768:100"
>
> # file: dst-fake-super/bar
> user.rsync.%stat="120777 0,0 32768:100"
>
> # file: dst-fake-super/foo
> user.rsync.%stat="100444 0,0 32768:100"
>
> .Dave.
In an attempt to avoid the above problem, one might try using a --chmod
option to ensure that the destination files are not world-writable (here
we use a rather silly chmod, just to make it more obvious what is -- and
isn't -- affected):
<code>
backup$ rsync -av src/ dst-nonsuper/
backup$ rsync -av --chmod=D0700,Fu=rx,g=,o=x src/ dst-chmod-501/
backup$ rsync -av --fake-super --chmod=D0700,Fu=rx,g=,o=x src/
dst-fake-chmod-501/
backup$ getfattr -d -R .
# file: dst-fake-chmod-501
user.rsync.%stat="40701 0,0 32768:100"
# file: dst-fake-chmod-501/bar
user.rsync.%stat="120777 0,0 32768:100"
# file: dst-fake-chmod-501/foo
user.rsync.%stat="100501 0,0 32768:100"
backup$ ll -R */
./src:
total 8
drwxr-xr-x 2 dg users 4096 Feb 3 11:59 ./
drwxrwxr-x 6 dg users 4096 Feb 3 17:16 ../
lrwxrwxrwx 1 dg users 3 Feb 3 11:59 bar -> foo
-r--r--r-- 1 dg users 0 Feb 3 11:59 foo
./dst-nonsuper:
total 8
drwxr-xr-x 2 backup users 4096 Feb 3 11:59 ./
drwxrwxr-x 6 dg users 4096 Feb 3 17:16 ../
lrwxrwxrwx 1 backup users 3 Feb 3 11:59 bar -> foo
-r--r--r-- 1 backup users 0 Feb 3 11:59 foo
./dst-chmod-501:
total 8
drwx-----x 2 backup users 4096 Feb 3 11:59 ./
drwxrwxr-x 6 dg users 4096 Feb 3 17:16 ../
lrwxrwxrwx 1 backup users 3 Feb 3 11:59 bar -> foo*
-r-x-----x 1 backup users 0 Feb 3 11:59 foo*
./dst-fake-chmod-501:
total 12
drwx-----x 2 backup backup 4096 Feb 3 11:59 ./
drwxrwxr-x 6 dg users 4096 Feb 3 17:16 ../
-rwxrwxrwx 1 backup backup 3 Feb 3 11:59 bar*
-rwx-----x 1 backup backup 0 Feb 3 11:59 foo*
</code>
In non-fake mode, the permissions on the copies incorporate the --chmod
specification, except for the symlink, whose mode is unchanged at 0777
but irrelevant. In fake mode, the tweaks from the --chmod affect the
stored value in the xattr, and to some extent the mode of the copy,
except that fake-mode copies always include u+rwX, But the symlink is
still stored as a world-writable plain file.
.Dave.
More information about the rsync
mailing list