Bug 6027 - Error when rsync encounters empty symlinks
Summary: Error when rsync encounters empty symlinks
Status: RESOLVED FIXED
Alias: None
Product: rsync
Classification: Unclassified
Component: core (show other bugs)
Version: 3.0.4
Hardware: x86 Linux
: P3 minor (vote)
Target Milestone: ---
Assignee: Wayne Davison
QA Contact: Rsync QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-01-13 08:20 UTC by Kai Krakow
Modified: 2009-02-05 21:14 UTC (History)
0 users

See Also:


Attachments
Don't send a symlink with an empty target name (567 bytes, patch)
2009-01-13 13:53 UTC, Wayne Davison
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kai Krakow 2009-01-13 08:20:07 UTC
Recently I needed to recover a system with a damaged file system. After fsck there were some symlinks broken, pointing to nowhere (or better pointing to an empty file name, it showed up as "filename ->" in "ls -al").

Rsync fails to sync these symlinks, it just breaks with the following message:
ERROR: buffer overflow in recv_file_entry

Instead I wished either rsync correctly sync'ing these - or if empty symlinks cannot be created it should skip these and issue a warning but not exit with a buffer overflow.

Manually deleting the broken symlinks from the source solved this (thus setting this bug to "minor"), but it was much work and I needed to recover rsync several times.
Comment 1 Wayne Davison 2009-01-13 13:53:27 UTC
Created attachment 3872 [details]
Don't send a symlink with an empty target name

This patch should fix the issue by culling a link without a valid target from the file list.  I can't create such a link, so I can't test this.
Comment 2 Matt McCutchen 2009-01-13 22:36:43 UTC
In general, rsync is not designed to cope with corrupt filesystems, but if it handles a file with an empty name, I suppose it should handle this too.  I had a slightly different patch:

https://mattmccutchen.net/rsync/rsync.git/commitdiff/7c18847f1608618134ffd166d97952177502d998

The place where the code is hooked is a matter of taste; I preferred to catch the invalid data as soon as possible to avoid any potential surprises.  On the other hand, the error message definitely needs to be more clearly distinct from the "symlink has no referent" message that can happen with --copy-links.

It may not be easy to test the code on a true empty symlink, but I at least saw the code path in action by temporarily hacking readlink_stat to substitute an empty string as the target if the symlink's name began with "z".  :)
Comment 3 Matt McCutchen 2009-01-13 22:43:11 UTC
On second thought, maybe I should let --copy-unsafe-links work on a virtual filesystem where some symlinks appear to have an empty target string but can be followed.  More generally, what if readlink returns an error but the symlink can be followed?
Comment 4 Matt McCutchen 2009-01-31 00:17:39 UTC
Thoughts on comment #3?
Comment 5 Wayne Davison 2009-02-04 20:30:48 UTC
The thing I dislike about both my patch and yours is that it stops the receiving side from removing a symlink that shouldn't be there just because it has a 0-length value.  Because of this, I moved the check to where it would only affect the sending of the file list to the receiver.

I have checked in a fix to prevent a fatal error for a 0-length symlink.

As for you comment #3, I am missing what you are driving at.  If readlink() doesn't work on a symlink, how can something read the link to follow it?
Comment 6 Matt McCutchen 2009-02-05 21:14:23 UTC
Looks good.

As for comment #3: on Linux, each filesystem implements independent "follow_link" and "readlink" functions, so when you follow a symlink, the filesystem can send you anywhere it likes independent of the return value of readlink.  /proc/*/fd/* symlinks for pipes and sockets work this way.  Thus, I was wondering how --copy-unsafe-links should handle a symlink that cannot be read (or returns a zero-length target) but can still be followed.  Anyone who cares about this corner case can comment on the mailing list.