Browse code

bb#1856

aCaB authored on 2010/03/06 06:17:46
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Fri Mar  5 22:16:45 CET 2010 (acab)
2
+-----------------------------------
3
+ * libclamav: don't cache clean results due to EMAX - final fix for bb#1856
4
+
1 5
 Fri Mar  5 22:01:20 CET 2010 (tk)
2 6
 ---------------------------------
3 7
  * libclamav: fix scanning of utf16 data (bb#1853)
... ...
@@ -263,6 +263,7 @@ struct node { /* a node */
263 263
     struct node *next;
264 264
     struct node *prev;
265 265
     uint32_t size;
266
+    uint32_t minrec;
266 267
 };
267 268
 
268 269
 struct cache_set { /* a tree */
... ...
@@ -367,7 +368,7 @@ static int printtree(struct cache_set *cs, struct node *n, int d) {
367 367
 
368 368
 /* Looks up a node and splays it up to the root of the tree */
369 369
 static int splay(int64_t *md5, size_t len, struct cache_set *cs) {
370
-    struct node next = {{0, 0}, NULL, NULL, NULL, NULL, NULL, 0}, *right = &next, *left = &next, *temp, *root = cs->root;
370
+    struct node next = {{0, 0}, NULL, NULL, NULL, NULL, NULL, 0, 0}, *right = &next, *left = &next, *temp, *root = cs->root;
371 371
     int comp, found = 0;
372 372
 
373 373
     if(!root)
... ...
@@ -426,7 +427,7 @@ static int splay(int64_t *md5, size_t len, struct cache_set *cs) {
426 426
 
427 427
 
428 428
 /* Looks up an hash in the tree and maintains the replacement chain */
429
-static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size) {
429
+static inline int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size, uint32_t reclevel) {
430 430
     int64_t hash[2];
431 431
 
432 432
     memcpy(hash, md5, 16);
... ...
@@ -450,8 +451,6 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
450 450
 	    printf("\n");
451 451
 	}
452 452
 #endif
453
-#define TO_END_OF_CHAIN
454
-#ifdef TO_END_OF_CHAIN
455 453
     	if(q) {
456 454
 	    if(o)
457 455
 		o->next = q;
... ...
@@ -463,18 +462,6 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
463 463
 	    p->next = NULL;
464 464
 	    cs->last = p;
465 465
 	}
466
-#else
467
-	if(cs->last != p) {
468
-	    if(cs->last == q) cs->last = p;
469
-	    if(o) o->next = q;
470
-	    else cs->first = q;
471
-	    p->next = q->next;
472
-	    if(q->next) q->next->prev = p;
473
-	    q->next = p;
474
-	    q->prev = o;
475
-	    p->prev = q;
476
-	}
477
-#endif
478 466
 #ifdef PRINT_CHAINS
479 467
 	{
480 468
 	    struct node *x = cs->first;
... ...
@@ -492,7 +479,8 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
492 492
 	    printf("\n");
493 493
 	}
494 494
 #endif
495
-	return 1;
495
+	if(reclevel >= p->minrec)
496
+	    return 1;
496 497
     }
497 498
     return 0;
498 499
 }
... ...
@@ -500,13 +488,16 @@ static int cacheset_lookup(struct cache_set *cs, unsigned char *md5, size_t size
500 500
 /* If the hash is present nothing happens.
501 501
    Otherwise a new node is created for the hash picking one from the begin of the chain.
502 502
    Used nodes are moved to the end of the chain */
503
-static void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size) {
503
+static inline void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size, uint32_t reclevel) {
504 504
     struct node *newnode;
505 505
     int64_t hash[2];
506 506
 
507 507
     memcpy(hash, md5, 16);
508
-    if(splay(hash, size, cs))
508
+    if(splay(hash, size, cs)) {
509
+	if(cs->root->minrec > reclevel)
510
+	    cs->root->minrec = reclevel;
509 511
 	return; /* Already there */
512
+    }
510 513
 
511 514
     ptree("1:\n");
512 515
     if(printtree(cs, cs->root, 0)) {
... ...
@@ -607,6 +598,7 @@ static void cacheset_add(struct cache_set *cs, unsigned char *md5, size_t size)
607 607
     newnode->digest[1] = hash[1];
608 608
     newnode->up = NULL;
609 609
     newnode->size = size;
610
+    newnode->minrec = reclevel;
610 611
     cs->root = newnode;
611 612
 
612 613
     ptree("3: %lld\n", hash[1]);
... ...
@@ -674,7 +666,7 @@ void cli_cache_destroy(struct cl_engine *engine) {
674 674
 }
675 675
 
676 676
 /* Looks up an hash in the proper tree */
677
-static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache) {
677
+static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache, uint32_t reclevel) {
678 678
     unsigned int key = getkey(md5);
679 679
     int ret = CL_VIRUS;
680 680
     struct CACHE *c;
... ...
@@ -685,7 +677,7 @@ static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache
685 685
 	return ret;
686 686
     }
687 687
 
688
-    ret = (cacheset_lookup(&c->cacheset, md5, len)) ? CL_CLEAN : CL_VIRUS;
688
+    ret = (cacheset_lookup(&c->cacheset, md5, len, reclevel)) ? CL_CLEAN : CL_VIRUS;
689 689
     pthread_mutex_unlock(&c->mutex);
690 690
     /* if(ret == CL_CLEAN) cli_warnmsg("cached\n"); */
691 691
     return ret;
... ...
@@ -694,6 +686,7 @@ static int cache_lookup_hash(unsigned char *md5, size_t len, struct CACHE *cache
694 694
 /* Adds an hash to the cache */
695 695
 void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) {
696 696
     unsigned int key = getkey(md5);
697
+    uint32_t level;
697 698
     struct CACHE *c;
698 699
 
699 700
     if(!ctx || !ctx->engine || !ctx->engine->cache)
... ...
@@ -709,14 +702,15 @@ void cache_add(unsigned char *md5, size_t size, cli_ctx *ctx) {
709 709
     cacheset_add(&c->cacheset, md5, size, ctx->engine->mempool);
710 710
 #else
711 711
 #ifdef USE_SPLAY
712
-    cacheset_add(&c->cacheset, md5, size);
712
+    cacheset_add(&c->cacheset, md5, size, level);
713 713
 #else
714 714
 #error #define USE_SPLAY or USE_LRUHASHCACHE
715 715
 #endif
716 716
 #endif
717 717
 
718 718
     pthread_mutex_unlock(&c->mutex);
719
-    cli_dbgmsg("cache_add: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]);
719
+    level =  (*ctx->fmap && (*ctx->fmap)->dont_cache_flag) ? ctx->recursion : 0;
720
+    cli_dbgmsg("cache_add: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x (level %u)\n", md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15], level);
720 721
     return;
721 722
 }
722 723
 
... ...
@@ -745,7 +739,7 @@ int cache_check(unsigned char *hash, cli_ctx *ctx) {
745 745
 	cli_md5_update(&md5, buf, readme);
746 746
     }
747 747
     cli_md5_final(hash, &md5);
748
-    ret = cache_lookup_hash(hash, map->len, ctx->engine->cache);
748
+    ret = cache_lookup_hash(hash, map->len, ctx->engine->cache, ctx->recursion);
749 749
     cli_dbgmsg("cache_check: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x is %s\n", hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15], (ret == CL_VIRUS) ? "negative" : "positive");
750 750
     return ret;
751 751
 }