https://bugzilla.samba.org/show_bug.cgi?id=9798
--- Comment #2 from Vijay Nag <viju...@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. -- Please use reply-all for most replies to avoid omitting the mailing list. To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html