| ... | ... |
@@ -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 |
} |