Mailing List Archive

crash when checking firefox/iceweasel deb files
Hiya,

(that's on debian testing amd64 with libclamav6 0.97.2+dfsg-1)

I had a few c-icap crashes on scanning some debian packages for firefox
(for instance:
http://ftp.se.debian.org/debian/pool/main/i/iceweasel/iceweasel_7.0.1-2_amd64.deb)

It can be reproduced on amd64 with
clamscan --max-recursion=5 iceweasel_7.0.1-2_amd64.deb

That gives:
*** glibc detected *** clamscan: double free or corruption
(out): 0x0000000002191fd0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x72606)[0x7f370d743606]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c)[0x7f370d74833c]
/usr/lib/libclamav.so.6(html_tag_arg_free+0x25)[0x7f370dd62b15]
/usr/lib/libclamav.so.6(+0xf2862)[0x7f370dd63862]
/usr/lib/libclamav.so.6(html_normalise_map+0x23)[0x7f370dd66763]
[...]

That's on the free(ctx.fmap) in scanners.c

Running valgrind:

==31006== Invalid write of size 8
==31006== at 0x62D9D72: magic_scandesc (scanners.c:1985)
==31006== by 0x62E0C14: fileblobScan (blob.c:639)
==31006== by 0x62E026A: fileblobScanAndDestroy (blob.c:399)
==31006== by 0x62E547B: saveTextPart (mbox.c:2589)
==31006== by 0x62E45C6: parseEmailBody (mbox.c:2100)
==31006== by 0x62E136F: cli_parse_mbox (mbox.c:511)
==31006== by 0x62E0D69: cli_mbox (mbox.c:311)
==31006== by 0x62BB4B3: cli_scanmail (scanners.c:1553)
==31006== by 0x62DACC8: magic_scandesc (scanners.c:2164)
==31006== by 0x62D97C5: cli_scanfile (scanners.c:2489)
==31006== by 0x62D995A: cli_scandir (scanners.c:146)
==31006== by 0x62BB3F1: cli_scanhtml (scanners.c:1019)
==31006== Address 0x10a7a738 is 0 bytes after a block of size
56 alloc'd
==31006== at 0x4C25E84: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==31006== by 0x6AD64F1: cli_calloc (others_common.c:214)
==31006== by 0x62DC7D7: cl_scandesc_callback
(scanners.c:2425)
==31006== by 0x601618F: srvclamav_end_of_data_handler
(srv_clamav.c:502)
==31006== by 0x40B76C: do_request (in /usr/bin/c-icap)
==31006== by 0x40BA0B: process_request (in /usr/bin/c-icap)
==31006== by 0x4146A9: thread_main (in /usr/bin/c-icap)
==31006== by 0x4E33B3F: start_thread (pthread_create.c:304)

fmap is calloced as an array of maxreclevel + 2 pointers.

I can definitely see fmap being increased past that in gdb (gdb
output below).

This patch makes the problem go away but it's probably not the
right fix as it rather seems that there's at least one place where
recursion is not increased where it should be. See comments in gdb
output for more info.

diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index c7a152c..37bc9f3 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -2624,7 +2624,7 @@ int cl_scandesc_callback(int desc, const char **virname,
unsigned long int *scan
ctx.container_size = 0;
ctx.dconf = (struct cli_dconf *) engine->dconf;
ctx.cb_ctx = context;
- ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2);
+ ctx.fmap = cli_calloc(ctx.engine->maxreclevel + 3, sizeof(fmap_t *));
if(!ctx.fmap)
return CL_EMEM;
if (!(ctx.hook_lsig_matches = cli_bitset_init())) {



GDB Output (the bt output is not useful so not included):

> Hardware watchpoint 2: ctx.fmap
>
> Old value = (fmap_t **) 0x0
> New value = (fmap_t **) 0xe52a00
> cl_scandesc_callback (desc=9, virname=<optimized out>, scanned=<optimized out>, engine=<optimized out>, scanoptions=<optimized out>, context=<optimized out>) at scanners.c:2426
> 2426 if(!ctx.fmap)
> (gdb)
> Continuing.
> Hardware watchpoint 2: ctx.fmap
>
> Old value = (fmap_t **) 0xe52a00
> New value = (fmap_t **) 0xe52a08
> magic_scandesc (desc=9, ctx=0x7f1ebbd54c00, type=CL_TYPE_ANY) at scanners.c:1985
> 1985 if(!(*ctx->fmap = fmap(desc, 0, sb.st_size))) {
> (gdb) break
> Breakpoint 4 at 0x7f1ec4438d6a: file scanners.c, line 1985.
> (gdb) commands 4
> Type commands for breakpoint(s) 4, one per line.
> End with a line saying just "end".
> >p ctx->fmap
> >p ctx->recursion
> >cont
> >end
> (gdb) cont
> Continuing.
> Hardware watchpoint 3: ctx.recursion
>
> Old value = 0
> New value = 1
> magic_scandesc (desc=9, ctx=0x7f1ebbd54c00, type=CL_TYPE_BINARY_DATA) at scanners.c:2077
> 2077 switch(type) {
> (gdb)
> Continuing.
> Hardware watchpoint 3: ctx.recursion
>
> Old value = 1
> New value = 0
> magic_scandesc (desc=9, ctx=0x7f1ebbd54c00, type=<optimized out>) at scanners.c:2314
> 2314 if(ret == CL_VIRUS) {
> (gdb)
> Continuing.
> [New Thread 0x7f1eba26b700 (LWP 2029)]
>
> Watchpoint 2 deleted because the program has left the block in
> which its expression is valid.

Here recursion not increased but magic_scandesc reentered somehow via
cli_scanraw() -> ??? -> cli_bcapi_extract_new().

> magic_scandesc (desc=10, ctx=0x7f1ebbd54c00, type=CL_TYPE_ANY) at scanners.c:1985
> 1985 if(!(*ctx->fmap = fmap(desc, 0, sb.st_size))) {
> $1 = (fmap_t **) 0xe52a10
> $2 = 0
> [...]
> Breakpoint 4, magic_scandesc (desc=16, ctx=0x7f1ebbd54c00, type=CL_TYPE_ANY) at scanners.c:1985
> 1985 if(!(*ctx->fmap = fmap(desc, 0, sb.st_size))) {
> $1163 = (fmap_t **) 0xe52a38
> $1164 = 5

Recursion is 5, and we're writing at 0xe52a38, 0x38 bytes (7 * 8) after 0xe52a00 returned by calloc(8,7).

--
Stephane

_______________________________________________
http://lurker.clamav.net/list/clamav-devel.html
Please submit your patches to our Bugzilla: http://bugs.clamav.net
Re: crash when checking firefox/iceweasel deb files [ In reply to ]
On 10/07/2011 04:33 PM, Stephane CHAZELAS wrote:
> Hiya,
>
> (that's on debian testing amd64 with libclamav6 0.97.2+dfsg-1)
>
> I had a few c-icap crashes on scanning some debian packages for firefox
> (for instance:
> http://ftp.se.debian.org/debian/pool/main/i/iceweasel/iceweasel_7.0.1-2_amd64.deb)
>
> It can be reproduced on amd64 with
> clamscan --max-recursion=5 iceweasel_7.0.1-2_amd64.deb
>
> That gives:
> *** glibc detected *** clamscan: double free or corruption
> [...]
> Here recursion not increased but magic_scandesc reentered somehow via
> cli_scanraw() -> ??? -> cli_bcapi_extract_new().

Thanks for the report.
There were only 2 bytecodes using that API, so I dropped them until the API is fixed in libclamav
(at which point I will readd them).

Bytecode.cvd 146 and 147 should not crash anymore, can you confirm (once you get the update via freshclam, in ~15m)?

Best regards,
--Edwin
_______________________________________________
http://lurker.clamav.net/list/clamav-devel.html
Please submit your patches to our Bugzilla: http://bugs.clamav.net
Re: crash when checking firefox/iceweasel deb files [ In reply to ]
2011-10-07, 17:27(+03), Török Edwin:
[...]
>>- ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2);
>>+ ctx.fmap = cli_calloc(ctx.engine->maxreclevel + 3, sizeof(fmap_t *));
[...]
>> Here recursion not increased but magic_scandesc reentered somehow via
>> cli_scanraw() -> ??? -> cli_bcapi_extract_new().
[...]
> There were only 2 bytecodes using that API, so I dropped them
> until the API is fixed in libclamav (at which point I will
> readd them).
>
> Bytecode.cvd 146 and 147 should not crash anymore, can you
> confirm (once you get the update via freshclam, in ~15m)?
[...]

Thanks Török,

I do confirm it no longer crashes.

BTW, though my WA above is not the right fix, it does fix the order of
arguments to the cli_calloc(nmemb,size)

--
Stephane

_______________________________________________
http://lurker.clamav.net/list/clamav-devel.html
Please submit your patches to our Bugzilla: http://bugs.clamav.net