Bug 4855 - skipped local filters cause segfault while deleting (-rFR --delete)
Summary: skipped local filters cause segfault while deleting (-rFR --delete)
Status: ASSIGNED
Alias: None
Product: rsync
Classification: Unclassified
Component: core (show other bugs)
Version: 3.0.0
Hardware: x86 Linux
: P3 normal (vote)
Target Milestone: ---
Assignee: Wayne Davison
QA Contact: Rsync QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-02 20:04 UTC by wolfgang.mayer
Modified: 2009-11-13 00:24 UTC (History)
0 users

See Also:


Attachments
quick fix to avoid crash (1.60 KB, patch)
2007-08-02 20:06 UTC, wolfgang.mayer
no flags Details
avoid crash (rsync 3.0.0cvs) (1.67 KB, patch)
2007-08-02 20:06 UTC, wolfgang.mayer
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description wolfgang.mayer 2007-08-02 20:04:57 UTC
It seems that some per-directory filters are skipped when deleting under
certain circumstances (options -rFR --delete, more than one sync
source, rsync 2.6.9 and 3.0.0cvs). This eventually leads to a segmentation violation (double free).

To reproduce:
$ mkdir -p dst a/aa/aaa a/ab b/bb/bbb/bbbb
$ rsync --delete -F -R -rvvv a b/bb/bbb/bbbb dst/
$ rsync --delete -F -R -rvvv a b/bb/bbb/bbbb dst/

While the first rsync succeeds, the second run aborts 
(--delete-before and --delete-after exhibit the same problem).

Here's the log of the second invocation:

building file list ...
[sender] make_file(a,*,2)
[sender] pushing filter list [per-dir .rsync-filter]
[sender] parse_filter_file(/.rsync-filter,c00,4) [not found]
[sender] parse_filter_file(/home/.rsync-filter,c00,4) [not found]
[sender] parse_filter_file(/home/wolfgang/.rsync-filter,c00,4) [not found]
[sender] parse_filter_file(/home/wolfgang/tmp/.rsync-filter,c00,4) [not found]
[sender] parse_filter_file(/home/wolfgang/tmp/rsync/.rsync-filter,c00,4) [not found]
[sender] parse_filter_file(/home/wolfgang/tmp/rsync/a/.rsync-filter,c00,4) [not found]
[sender] make_file(a/aa,*,2)
[sender] make_file(a/ab,*,2)
[sender] pushing filter list [per-dir .rsync-filter]
[sender] parse_filter_file(/home/wolfgang/tmp/rsync/a/aa/.rsync-filter,c00,4) [not found]
[sender] make_file(a/aa/aaa,*,2)
[sender] pushing filter list [per-dir .rsync-filter]
[sender] parse_filter_file(/home/wolfgang/tmp/rsync/a/aa/aaa/.rsync-filter,c00,4) [not found]
[sender] popping filter list [per-dir .rsync-filter]
[sender] popping filter list [per-dir .rsync-filter]
[sender] pushing filter list [per-dir .rsync-filter]
[sender] parse_filter_file(/home/wolfgang/tmp/rsync/a/ab/.rsync-filter,c00,4) [not found]
[sender] popping filter list [per-dir .rsync-filter]
[sender] popping filter list [per-dir .rsync-filter]
[sender] make_file(b,*,2)
[sender] make_file(b/bb,*,2)
[sender] make_file(b/bb/bbb,*,2)
[sender] make_file(b/bb/bbb/bbbb,*,2)
[sender] pushing filter list [per-dir .rsync-filter]
[sender] parse_filter_file(/home/wolfgang/tmp/rsync/b/bb/bbb/bbbb/.rsync-filter,c00,4) [not found]
[sender] popping filter list [per-dir .rsync-filter]
done
server_recv(2) starting pid=13865
send_file_list done
send_files starting
recv_file_name(a)
recv_file_name(a/aa)
recv_file_name(a/ab)
recv_file_name(a/aa/aaa)
recv_file_name(b)
recv_file_name(b/bb)
recv_file_name(b/bb/bbb)
recv_file_name(b/bb/bbb/bbbb)
received 8 names
recv_file_list done
get_local_name count=8 dst/
recv_files(8) starting
generator starting pid=13865 count=8
deleting in a
delete_in_dir(a)
[generator] pushing filter list [per-dir .rsync-filter]
[generator] parse_filter_file(/.rsync-filter,c00,4) [not found]
[generator] parse_filter_file(/home/.rsync-filter,c00,4) [not found]
[generator] parse_filter_file(/home/wolfgang/.rsync-filter,c00,4) [not found]
[generator] parse_filter_file(/home/wolfgang/tmp/.rsync-filter,c00,4) [not found]
[generator] parse_filter_file(/home/wolfgang/tmp/rsync/.rsync-filter,c00,4) [not found]
[generator] parse_filter_file(/home/wolfgang/tmp/rsync/dst/.rsync-filter,c00,4) [not found]
[generator] parse_filter_file(/home/wolfgang/tmp/rsync/dst/a/.rsync-filter,c00,4) [not found]
[generator] make_file(a/aa,*,2)
[generator] make_file(a/ab,*,2)
delete_in_dir(a/aa)
[generator] pushing filter list [per-dir .rsync-filter]
[generator] parse_filter_file(/home/wolfgang/tmp/rsync/dst/a/aa/.rsync-filter,c00,4) [not found]
[generator] make_file(a/aa/aaa,*,2)
delete_in_dir(a/aa/aaa)
[generator] pushing filter list [per-dir .rsync-filter]
[generator] parse_filter_file(/home/wolfgang/tmp/rsync/dst/a/aa/aaa/.rsync-filter,c00,4) [not found]
delete_in_dir(a/ab)
[generator] popping filter list [per-dir .rsync-filter]
[generator] popping filter list [per-dir .rsync-filter]
[generator] pushing filter list [per-dir .rsync-filter]
[generator] parse_filter_file(/home/wolfgang/tmp/rsync/dst/a/ab/.rsync-filter,c00,4) [not found]
deleting in b/bb/bbb/bbbb
delete_in_dir(b/bb/bbb/bbbb)
[generator] pushing filter list [per-dir .rsync-filter]
[generator] parse_filter_file(/home/wolfgang/tmp/rsync/dst/b/bb/bbb/bbbb/.rsync-filter,c00,4) [not found]
[generator] popping filter list [per-dir .rsync-filter]
[generator] popping filter list [per-dir .rsync-filter]
rsync: connection unexpectedly closed (8 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(459) [sender=2.6.8]
_exit_cleanup(code=12, file=io.c, line=459): about to call exit(12)
*** glibc detected *** rsync: double free or corruption (fasttop): 0x080ab3b8 ***



It seems that the root cause of the crash is due to the `.rsync-filter'
files in the parent directories of b/bb/bbb/bbbb are not
considered. However, when backing up from the directory, it is assumed that
those filters are present in the local filter stack. Therefore, invalid
pointers may be used when freeing local filter lists.
Comment 1 wolfgang.mayer 2007-08-02 20:06:12 UTC
Created attachment 2850 [details]
quick fix to avoid crash

I've attached patches for rsync 2.6.9 and 3.0.0cvs that avoid the segfault,
skip deleting files for affected directories and emit a warning. However,
my knowledge of rsync internals are too limited to assess how to address
the problem of skipped local filters and whether this is a feature or a bug
(the man page suggests it is a bug).
Comment 2 wolfgang.mayer 2007-08-02 20:06:38 UTC
Created attachment 2851 [details]
avoid crash (rsync 3.0.0cvs)
Comment 3 Wayne Davison 2007-08-04 15:47:19 UTC
Thanks for the report and patch.  I've checked in a fix that will ensure that the crash is avoided, and will be looking into making sure that all the filter files get loaded when working with --relative.
Comment 4 Matt McCutchen 2009-11-13 00:24:19 UTC
Is this fixed?  At least I don't get the crash in 3.0.6 or the latest development rsync.