Package: rsync
Version: 3.0.2-1
Severity: serious
Tags: patch
Hi,
I can consitently make rsync segfault when trying to sync the linux
kernel archive using version 3.0.2. It doesn't segfault using
2.6.9-2etch2. This has worked for weeks but started happening yesterday.
This is what I got from gdb:
Program received signal SIGSEGV, Segmentation fault.
#0 0x0000000000434b84 in hashtable_find (tbl=0x0, key=-1,
allocate_if_missing=0) at hashtable.c:59
59 int key64 = tbl->key64;
(gdb) bt
#0 0x0000000000434b84 in hashtable_find (tbl=0x0, key=-1,
allocate_if_missing=0) at hashtable.c:59
#1 0x0000000000430278 in check_prior (file=0x2ae3c6632e78, gnum=-1,
prev_ndx_p=0x7fffe8617564, flist_p=0x7fffe8617568) at hlink.c:269
#2 0x0000000000430433 in hard_link_check (file=0x2ae3c6632e78, ndx=799511,
fname=0x7fffe861ba30
"scm/linux/kernel/git/torvalds/linux-2.6.git/objects/pack/pack-447fe96131da71732243925546a8d62bef99bea2.idx",
statret=0,
sxp=0x7fffe861b870, itemizing=1, code=FLOG) at hlink.c:298
#3 0x00000000004112d6 in recv_generator (
fname=0x7fffe861ba30
"scm/linux/kernel/git/torvalds/linux-2.6.git/objects/pack/pack-447fe96131da71732243925546a8d62bef99bea2.idx",
file=0x2ae3c6632e78,
ndx=799511, itemizing=1, code=FLOG, f_out=3) at generator.c:1504
#4 0x00000000004139c2 in generate_files (f_out=3, local_name=0x0)
at generator.c:2214
#5 0x000000000041f651 in do_recv (f_in=3, f_out=3, local_name=0x0)
at main.c:839
#6 0x000000000041fdbe in client_run (f_in=3, f_out=3, pid=-1, argc=1,
argv=0x682338) at main.c:1077
#7 0x000000000043f035 in start_socket_client (
host=0x6827a8 "filehub.kernel.org", remote_argc=1, remote_argv=0x682330,
argc=1, argv=0x682338) at clientserver.c:132
#8 0x00000000004204c0 in start_client (argc=1, argv=0x682338) at main.c:1243
#9 0x0000000000420cf5 in main (argc=2, argv=0x682330) at main.c:1511
(gdb) frame 1
#1 0x0000000000430278 in check_prior (file=0x2ae3c6632e78, gnum=-1,
prev_ndx_p=0x7fffe8617564, flist_p=0x7fffe8617568) at hlink.c:269
269 if ((node = hashtable_find(prior_hlinks, gnum, 0)) != NULL) {
(gdb) p prior_hlinks
$1 = (struct hashtable *) 0x0
(gdb) p inc_recurse
$2 = 0
prior_hlinks only seems to be used in case of !inc_recurse, so I
have the feeling that I shouldn't be comming there in the first place.
I'm guessing that the hashtable_find() should be inside an if (inc_recurse)
as all other hashtable_find()'s are also doing that.
I've attached a patch that does that. It seems to be working.
PS: It's annoying that when a core file gets created that it's written
in destination path instead of the directory where I started rsync.
Kurt
--- hlink.c.old 2008-04-25 19:39:15.000000000 +0000
+++ hlink.c 2008-04-25 19:39:49.000000000 +0000
@@ -266,15 +266,18 @@
F_HL_PREV(file) = prev_ndx = F_HL_PREV(fp);
}
- if ((node = hashtable_find(prior_hlinks, gnum, 0)) != NULL) {
- assert(node->data != NULL);
- if (CVAL(node->data, 0) != 0) {
- *prev_ndx_p = -1;
- *flist_p = NULL;
- return node->data;
+ if (inc_recurse)
+ {
+ if ((node = hashtable_find(prior_hlinks, gnum, 0)) != NULL) {
+ assert(node->data != NULL);
+ if (CVAL(node->data, 0) != 0) {
+ *prev_ndx_p = -1;
+ *flist_p = NULL;
+ return node->data;
+ }
+ /* The prior file must have been skipped. */
+ F_HL_PREV(file) = -1;
}
- /* The prior file must have been skipped. */
- F_HL_PREV(file) = -1;
}
*prev_ndx_p = -1;