Crash in perl XS module.

Andy Fiddaman cyrus at fiddaman.net
Tue Sep 18 16:23:16 EDT 2007


I'm seeing a crash whenever a perl process exits that uses the Cyrus
IMAP.pm perl module.

The cleanup function in the IMAP.xs checks the reference count post
decrement rather than pre, therefore it double frees memory and ends
up calling imclient_destroy() twice for the same object.

The following is from the unpatched version save enabling the debug
lines that are already in IMAP.xs but commented out.

	localhost> ^D
	!DESTROY 100602e60 1
	closing
	!DESTROY 100602e60 1
	closing

closing means that imclient_close() is being called.

Core was generated by `/opt/perl/bin/perl -I/opt/cyrus/lib/site_perl
-MCyrus::IMAP::Shell -e shell --'.
Program terminated with signal 10, Bus error.
#0 0xffffffff7e00bf44 in imclient_eof (imclient=0x1006037f0) at
imclient.c:966
966 (*cmdcb->proc)(imclient, cmdcb->rock, &reply);
(gdb) where
#0 0xffffffff7e00bf44 in imclient_eof (imclient=0x1006037f0) at
imclient.c:966
#1 0xffffffff7e009588 in imclient_close (imclient=0x1006037f0)
at imclient.c:309
#2 0xffffffff7e0085a0 in XS_Cyrus__IMAP_DESTROY ()
from /opt/cyrus/lib/site_perl/5.8.8/sun4-solaris/auto/Cyrus/IMAP/IMAP.so

(gdb) print cmdcb
$1 = (struct imclient_cmdcallback *) 0x11

(gdb) print *imclient
$2 = {fd = 0, servername = 0x0, flags = 1,
outbuf = "\000xI\020\000\000\000\001\000R\tP\000\000\000\001\000`.P", '\0'
<repeats 11 times>,
"\001\000`<\200\000\000\000\001\000$$TH\000\000\000\001\000`A\200", '\0'
<repeats 11 times>, "\002\000\000\000\000\000\000\000\001\000R\v\220",
'\0' <repeats 19 times>, "\002\000\000\000A\000\000\000\001\000R\v", '\0'
<repeats 19 times>, "\002\000\000\000\000\000\000\000\001\000R\023\220",
'\0' <repeats 27 times>, "\001\000`G ", '\0' <repeats 27 times>,
"\001\000`J yyyy~\000\212I\000\000\000\001\000aETH", '\0' <repeats 83
times>, "\001\000`7TH", '\0' <repeats 15 times>, "c", '\0' <repeats 51
times>...,
outptr = 0x2d75736572000024 <Address 0x2d75736572000024 out of bounds>,
outleft = 17,
outstart = 0x4c4f422729207b09 <Address 0x4c4f422729207b09 out of bounds>,
replybuf = 0x1006047f0 "",
replystart = 0x6465722064656275 <Address 0x6465722064656275 out of
bounds>,
replyliteralleft = 16, replylen = 2314894345321193533,
alloc_replybuf = 4301278864, state = 0x2d617574687a0000, maxplain = 0,
gensym = 3400001158362702717, readytag = 0, readytxt = 0x0,
cmdcallback = 0x11, callback_num = 1848073326, callback_alloc = 574294560,
callback = 0x2d6e6f746c730000, interact_results = 0x6400007375622061,
saslconn = 0x11, saslcompleted = 2032171901, tls_ctx = 0x2d73657276696365,
tls_conn = 0x205c26416464, tls_on = 0}



With the following patch it works fine:


--- cyrus-imapd-2.3.9.dist/perl/imap/IMAP.xs    2006-11-30 17:11:23.000000000 +0000
+++ cyrus-imapd-2.3.9/perl/imap/IMAP.xs 2007-09-05 14:52:23.800979396 +0000
@@ -320,7 +320,7 @@
        struct xscb *nx;
 CODE:
 /* fprintf(stderr, "!DESTROY %p %d\n", client, client->cnt); */
-       if (!--client->cnt) {
+       if (!client->cnt--) {
 /* printf("closing\n"); */
          imclient_close(client->imclient);
          while (client->cb) {


as can be seen with this debug output:

localhost> ^D
!DESTROY 100602e60 1
!DESTROY 100602e60 0
closing



More information about the Info-cyrus mailing list