... | ... |
@@ -400,13 +400,73 @@ static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
400 | 400 |
return ret; |
401 | 401 |
} |
402 | 402 |
|
403 |
+ |
|
404 |
+static int cli_scangzip_with_zib_from_the_80s(cli_ctx *ctx, unsigned char *buff) { |
|
405 |
+ int fd, ret, outsize = 0, bytes; |
|
406 |
+ fmap_t *map = *ctx->fmap; |
|
407 |
+ char *tmpname; |
|
408 |
+ gzFile gz; |
|
409 |
+ |
|
410 |
+ fd = dup(map->fd); |
|
411 |
+ if(fd < 0) |
|
412 |
+ return CL_EDUP; |
|
413 |
+ |
|
414 |
+ lseek(fd, 0, SEEK_SET); |
|
415 |
+ if(!(gz = gzdopen(fd, "rb"))) { |
|
416 |
+ close(fd); |
|
417 |
+ return CL_EOPEN; |
|
418 |
+ } |
|
419 |
+ |
|
420 |
+ if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) { |
|
421 |
+ cli_dbgmsg("GZip: Can't generate temporary file.\n"); |
|
422 |
+ gzclose(gz); |
|
423 |
+ return ret; |
|
424 |
+ } |
|
425 |
+ |
|
426 |
+ while((bytes = gzread(gz, buff, FILEBUFF)) > 0) { |
|
427 |
+ outsize += bytes; |
|
428 |
+ if(cli_checklimits("GZip", ctx, outsize, 0, 0)!=CL_CLEAN) |
|
429 |
+ break; |
|
430 |
+ if(cli_writen(fd, buff, bytes) != bytes) { |
|
431 |
+ close(fd); |
|
432 |
+ gzclose(gz); |
|
433 |
+ if(cli_unlink(tmpname)) { |
|
434 |
+ free(tmpname); |
|
435 |
+ return CL_EUNLINK; |
|
436 |
+ } |
|
437 |
+ free(tmpname); |
|
438 |
+ return CL_EWRITE; |
|
439 |
+ } |
|
440 |
+ } |
|
441 |
+ |
|
442 |
+ gzclose(gz); |
|
443 |
+ |
|
444 |
+ if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) { |
|
445 |
+ cli_dbgmsg("GZip: Infected with %s\n", *ctx->virname); |
|
446 |
+ close(fd); |
|
447 |
+ if(!ctx->engine->keeptmp) { |
|
448 |
+ if (cli_unlink(tmpname)) { |
|
449 |
+ free(tmpname); |
|
450 |
+ return CL_EUNLINK; |
|
451 |
+ } |
|
452 |
+ } |
|
453 |
+ free(tmpname); |
|
454 |
+ return CL_VIRUS; |
|
455 |
+ } |
|
456 |
+ close(fd); |
|
457 |
+ if(!ctx->engine->keeptmp) |
|
458 |
+ if (cli_unlink(tmpname)) ret = CL_EUNLINK; |
|
459 |
+ free(tmpname); |
|
460 |
+ return ret; |
|
461 |
+} |
|
462 |
+ |
|
403 | 463 |
static int cli_scangzip(cli_ctx *ctx) |
404 | 464 |
{ |
405 | 465 |
int fd, ret = CL_CLEAN; |
406 | 466 |
unsigned char buff[FILEBUFF]; |
407 | 467 |
char *tmpname; |
408 | 468 |
z_stream z; |
409 |
- size_t at = 0; |
|
469 |
+ size_t at = 0, outsize = 0; |
|
410 | 470 |
fmap_t *map = *ctx->fmap; |
411 | 471 |
|
412 | 472 |
cli_dbgmsg("in cli_scangzip()\n"); |
... | ... |
@@ -414,14 +474,7 @@ static int cli_scangzip(cli_ctx *ctx) |
414 | 414 |
memset(&z, 0, sizeof(z)); |
415 | 415 |
if((ret = inflateInit2(&z, MAX_WBITS + 16)) != Z_OK) { |
416 | 416 |
cli_dbgmsg("GZip: InflateInit failed: %d\n", ret); |
417 |
-#ifdef ZLIB_VERNUM |
|
418 |
- cli_dbgmsg("zlib version %s (%04x), build flags = 0x%lx, runtime version %s\n", |
|
419 |
- ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags(), zlibVersion()); |
|
420 |
-#else |
|
421 |
- cli_dbgmsg("zlib version %s, runtime version %s\n", |
|
422 |
- ZLIB_VERSION, zlibVersion()); |
|
423 |
-#endif |
|
424 |
- return CL_CLEAN; |
|
417 |
+ return cli_scangzip_with_zib_from_the_80s(ctx, buff); |
|
425 | 418 |
} |
426 | 419 |
|
427 | 420 |
if((ret = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) { |
... | ... |
@@ -462,6 +515,13 @@ static int cli_scangzip(cli_ctx *ctx) |
462 | 462 |
free(tmpname); |
463 | 463 |
return CL_EUNLINK; |
464 | 464 |
} |
465 |
+ free(tmpname); |
|
466 |
+ return CL_EWRITE; |
|
467 |
+ } |
|
468 |
+ outsize += sizeof(buff) - z.avail_out; |
|
469 |
+ if(cli_checklimits("GZip", ctx, outsize, 0, 0)!=CL_CLEAN) { |
|
470 |
+ at = map->len; |
|
471 |
+ break; |
|
465 | 472 |
} |
466 | 473 |
if(inf == Z_STREAM_END) { |
467 | 474 |
at -= z.avail_in; |
... | ... |
@@ -473,7 +533,7 @@ static int cli_scangzip(cli_ctx *ctx) |
473 | 473 |
|
474 | 474 |
inflateEnd(&z); |
475 | 475 |
|
476 |
- if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) { |
|
476 |
+ if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) { |
|
477 | 477 |
cli_dbgmsg("GZip: Infected with %s\n", *ctx->virname); |
478 | 478 |
close(fd); |
479 | 479 |
if(!ctx->engine->keeptmp) { |