... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Thu Sep 17 22:36:30 CEST 2009 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav/matcher-ac.c: implement word delimiter (B) as requested in bb#1631 |
|
4 |
+ |
|
1 | 5 |
Mon Sep 14 19:52:01 CEST 2009 (tk) |
2 | 6 |
---------------------------------- |
3 | 7 |
* freshclam: return 0 instead of 1 when database is up-to-date (bb#1312) |
... | ... |
@@ -51,6 +51,30 @@ |
51 | 51 |
#define AC_SPECIAL_LINE_END 4 |
52 | 52 |
#define AC_SPECIAL_BOUNDARY 5 |
53 | 53 |
|
54 |
+#define AC_BOUNDARY_LEFT 1 |
|
55 |
+#define AC_BOUNDARY_LEFT_NEGATIVE 2 |
|
56 |
+#define AC_BOUNDARY_RIGHT 4 |
|
57 |
+#define AC_BOUNDARY_RIGHT_NEGATIVE 8 |
|
58 |
+ |
|
59 |
+static char boundary[256] = { |
|
60 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, |
|
61 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
62 |
+ 3, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 1, 3, |
|
63 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, |
|
64 |
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
65 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, |
|
66 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
67 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
68 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
69 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
70 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
71 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
72 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
73 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
74 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
75 |
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
|
76 |
+}; |
|
77 |
+ |
|
54 | 78 |
int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern) |
55 | 79 |
{ |
56 | 80 |
struct cli_ac_node *pt, *next; |
... | ... |
@@ -698,7 +722,7 @@ int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigne |
698 | 698 |
break; \ |
699 | 699 |
\ |
700 | 700 |
case AC_SPECIAL_BOUNDARY: \ |
701 |
- if(memchr("\x22\x27\x20\x2f\x3d\x2d\x5f\x3e\x0a\x0d", b, 10)) \ |
|
701 |
+ if(boundary[b]) \ |
|
702 | 702 |
match = !special->negative; \ |
703 | 703 |
break; \ |
704 | 704 |
\ |
... | ... |
@@ -724,7 +748,7 @@ int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigne |
724 | 724 |
match = 0; \ |
725 | 725 |
} |
726 | 726 |
|
727 |
-inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uint32_t length, const struct cli_ac_patt *pattern, uint32_t *end) |
|
727 |
+inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uint32_t fileoffset, uint32_t length, const struct cli_ac_patt *pattern, uint32_t *end) |
|
728 | 728 |
{ |
729 | 729 |
uint32_t bp, match; |
730 | 730 |
uint16_t wc, i, j, specialcnt = pattern->special_pattern; |
... | ... |
@@ -745,6 +769,22 @@ inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uin |
745 | 745 |
} |
746 | 746 |
*end = bp; |
747 | 747 |
|
748 |
+ if(pattern->boundary & AC_BOUNDARY_LEFT) { |
|
749 |
+ match = !!(pattern->boundary & AC_BOUNDARY_LEFT_NEGATIVE); |
|
750 |
+ if(!fileoffset || (offset && (boundary[buffer[offset - 1]] == 1 || boundary[buffer[offset - 1]] == 3))) |
|
751 |
+ match = !match; |
|
752 |
+ if(!match) |
|
753 |
+ return 0; |
|
754 |
+ } |
|
755 |
+ |
|
756 |
+ if(pattern->boundary & AC_BOUNDARY_RIGHT) { |
|
757 |
+ match = !!(pattern->boundary & AC_BOUNDARY_RIGHT_NEGATIVE); |
|
758 |
+ if((length <= SCANBUFF) && (bp == length || boundary[buffer[bp]] >= 2)) |
|
759 |
+ match = !match; |
|
760 |
+ if(!match) |
|
761 |
+ return 0; |
|
762 |
+ } |
|
763 |
+ |
|
748 | 764 |
if(!(pattern->ch[1] & CLI_MATCH_IGNORE)) { |
749 | 765 |
bp += pattern->ch_mindist[1]; |
750 | 766 |
for(i = pattern->ch_mindist[1]; i <= pattern->ch_maxdist[1]; i++) { |
... | ... |
@@ -1001,7 +1041,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v |
1001 | 1001 |
} |
1002 | 1002 |
} |
1003 | 1003 |
pt = patt; |
1004 |
- if(ac_findmatch(buffer, bp, length, patt, &matchend)) { |
|
1004 |
+ if(ac_findmatch(buffer, bp, offset + bp - patt->prefix_length, length, patt, &matchend)) { |
|
1005 | 1005 |
while(pt) { |
1006 | 1006 |
if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) { |
1007 | 1007 |
pt = pt->next_same; |
... | ... |
@@ -1340,7 +1380,6 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex |
1340 | 1340 |
} |
1341 | 1341 |
} |
1342 | 1342 |
strcat(hexnew, start); |
1343 |
- strcat(hexnew, "()"); |
|
1344 | 1343 |
|
1345 | 1344 |
if(!(start = strchr(pt, ')'))) { |
1346 | 1345 |
mpool_free(root->mempool, newspecial); |
... | ... |
@@ -1353,6 +1392,24 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex |
1353 | 1353 |
error = CL_EMALFDB; |
1354 | 1354 |
break; |
1355 | 1355 |
} |
1356 |
+ |
|
1357 |
+ if(!strcmp(pt, "B")) { |
|
1358 |
+ if(!*start) { |
|
1359 |
+ new->boundary |= AC_BOUNDARY_RIGHT; |
|
1360 |
+ if(newspecial->negative) |
|
1361 |
+ new->boundary |= AC_BOUNDARY_RIGHT_NEGATIVE; |
|
1362 |
+ mpool_free(root->mempool, newspecial); |
|
1363 |
+ continue; |
|
1364 |
+ } else if(pt - 1 == hexcpy) { |
|
1365 |
+ new->boundary |= AC_BOUNDARY_LEFT; |
|
1366 |
+ if(newspecial->negative) |
|
1367 |
+ new->boundary |= AC_BOUNDARY_LEFT_NEGATIVE; |
|
1368 |
+ mpool_free(root->mempool, newspecial); |
|
1369 |
+ continue; |
|
1370 |
+ } |
|
1371 |
+ } |
|
1372 |
+ |
|
1373 |
+ strcat(hexnew, "()"); |
|
1356 | 1374 |
new->special++; |
1357 | 1375 |
newtable = (struct cli_ac_special **) mpool_realloc(root->mempool, new->special_table, new->special * sizeof(struct cli_ac_special *)); |
1358 | 1376 |
if(!newtable) { |