Bug 9594 - Error transferring user and non-user xattr using --fake-super under Linux
Summary: Error transferring user and non-user xattr using --fake-super under Linux
Alias: None
Product: rsync
Classification: Unclassified
Component: core (show other bugs)
Version: 3.1.0
Hardware: All Linux
: P5 normal (vote)
Target Milestone: ---
Assignee: Wayne Davison
QA Contact: Rsync QA Contact
Depends on:
Reported: 2013-01-24 17:39 UTC by Chemist
Modified: 2014-05-26 21:09 UTC (History)
2 users (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Chemist 2013-01-24 17:39:24 UTC
I'm using rsync -aX as root on the sender (local) and --fake-super on the receiver (remote) to preserve attributes. I'm using version 3.1.0dev as I needed a solution to Bug 8201 (https://bugzilla.samba.org/show_bug.cgi?id=8201). I get the error "could not find xattr #1 for [foo]" when trying to transfer a file that has both a non-user extended attribute with a long string value AND a user extended attribute where the name of the user EA preceeds "user.rsync" in lexical sort order. The error is triggered only if the transfer is remote AND rsync is run as root on the local/sender side so both non-user and user attrs are transferred.

Steps to reproduce:
1. sudo touch foo
2. sudo setfattr -n user.rsx -v "1" foo ## user.rsx sorts before user.rsync
3. sudo setfattr -n security.selinux -v "system_u:object_r:cachefiles_var_t:s0" foo ## non-user EA with a long string value
5. sudo rsync -i -aOzAX --numeric-ids --rsync-path="rsync --fake-super" foo user@remote:/tmp/ ## user does not have root access on host remote

Actual Results:
  <f+++++++++ foo
  [receiver] could not find xattr #1 for foo
  rsync error: protocol incompatibility (code 2) at xattrs.c(620) [receiver=3.1.0dev]

Expected Results: no error, file and xattrs transferred successfully

System details:
Local/sender and remote/receiver are RHEL 6.3 with rsync 3.1.0dev
Comment 1 Kuba Ober 2014-04-30 01:20:39 UTC
I can reproduce under 3.1.1pre1. The cause of the problem is as follows:

Note that the rsync_xa list items contain the xattr name and value *but also* an attribute *index* (num!). 

1. The sender is sorting the rsync_xa list alphabetically on the xattr name in rsync_xal_get. The attribute indices (num members) are set *after this sort*.

2. The receiver then proceeds to append RSYNC_PREFIX ("user.rsync.") to the xattr name in receive_xattr, and resorts the list. Now the attribute indices do not match the list order.

3. The receiver then proceeds to iterate through this list in recv_xattr_request with the assumption that the 
num indices are ascending within the list. The lexicographic sort performed in step 2 above breaks this assumption.

Since I don't understand why the list needs to be lexicographically sorted at all, I don't know which of the two fixes below would be desirable: 

Fix 1: Don't sort the list in receive_xattr iff HAVE_LINUX_XATTR is defined.
Fix 2: Don't assume that the list indices are sorted in recv_xattr_request. The change would be from

while (cnt && rxa->num < num) {


while (cnt && rxa->num != num) {

Cheers, Kuba
Comment 2 Wayne Davison 2014-05-26 21:09:25 UTC
Yeah, the bug seems to be that the receiver is aborting the scan for the rxa->num item too soon when the sorting of the items caused the num values to be scrambled. I am applying (essentially) your 2nd fix to the code.  Thanks for diagnosing the issue!