[Bug 9798] rsync crash with SIGSEGV when read time out happens
samba-bugs at samba.org
samba-bugs at samba.org
Mon Apr 22 09:26:41 MDT 2013
https://bugzilla.samba.org/show_bug.cgi?id=9798
--- Comment #2 from Vijay Nag <vijunag at gmail.com> 2013-04-22 15:26:41 UTC ---
(In reply to comment #1)
> Please retry with a current version of rsync. Your 3.0.2 version is 5 years
> old.
Crash is observed in the latest rsync. I checked the diff with the latest one
and
with 3.0.2
I think rsync is not handling EILSEQ error returned by iconv(3). Here are
couple of observations.
1>
while (icnt) {
retVal = -1;
while (iconv(ic, &ibuf, &icnt, &obuf, &ocnt) == (size_t)-1 || retVal == -1)
{
errno = EILSEQ;
if (errno == EINTR)
continue;
if (errno == EINVAL) {
if (!(flags & ICB_INCLUDE_INCOMPLETE))
goto finish;
} else if (errno == EILSEQ) {
if (!(flags & ICB_INCLUDE_BAD))
goto finish;
} else {
size_t opos = obuf - out->buf;
if (!(flags & ICB_EXPAND_OUT)) {
errno = E2BIG;
goto finish;
}
realloc_xbuf(out, out->size + 1024);
obuf = out->buf + opos;
ocnt += 1024;
continue;
}
*obuf++ = *ibuf++;
ocnt--, icnt--;
}
}
The condition checking "while(icnt)" is bad since icnt is size_t and there were
cases where icnt had wrapped causing it to crash.
2>
while (inbuf.len) {
iconvbufs(ic, &inbuf, &outbuf, 0);
ierrno = errno;
if (outbuf.len) {
filtered_fwrite(f, convbuf, outbuf.len, 0);
outbuf.len = 0;
}
if (!ierrno || ierrno == E2BIG)
continue;
fprintf(f, "\\#%03o", CVAL(inbuf.buf, inbuf.pos++));
inbuf.len--;
save_len = inbuf.len;
}
Lets assume iconvbufs is returning EILSEQ continuously there are
chances of "inbuf.len" wrapping again when inbuf.len reaches zero.
so again the "while(inbuf.len)" starts iterating from (size_t)-1 which is
0xffffff. This can lead to a crash again.
Best way to do this check is to save the (size_t)len to an integer and have
the while check "0 < save_len". This will make sure that inbuf.len can never
wrap. Let me know if it is plausible so that i can give you a patch. I have
tested it and it works.
+ int save_len = len;
INIT_CONST_XBUF(outbuf, convbuf);
INIT_XBUF(inbuf, (char*)buf, len, -1);
-while(inbuf.len)
+ while (0 < save_len) {
iconvbufs(ic, &inbuf, &outbuf, 0);
ierrno = errno;
if (outbuf.len) {
filtered_fwrite(f, convbuf, outbuf.len, 0);
outbuf.len = 0;
}
if (!ierrno || ierrno == E2BIG)
continue;
fprintf(f, "\\#%03o", CVAL(inbuf.buf, inbuf.pos++));
inbuf.len--;
save_len = inbuf.len;
}
--
Configure bugmail: https://bugzilla.samba.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
More information about the rsync
mailing list