Browse code

fix gzip handler

aCaB authored on 2010/02/10 00:36:14
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Feb  9 16:35:36 CET 2010 (acab)
2
+-----------------------------------
3
+ * libclamav/scanners.c: fix gzip handler
4
+
1 5
 Mon Feb  8 19:17:14 CET 2010 (tk)
2 6
 ---------------------------------
3 7
  * libclamav: prefix all engine detections with "Heuristics." (bb#1808)
... ...
@@ -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) {