Sorry it took so long to answer, I was on vacation.

On [08/25/03 03:21], Tomasz Kojm wrote:
> On Sun, 24 Aug 2003 18:20:36 -0400
> > This is getting pointless.  Give me the databsae, and I'll tell
> > you memory usage.
> 
> No, that's the problem I tried to explain you: you can't calculate
> exact memory usage "a priori".
> 

Why would you need to know memory usage a priori?  You can reavaluate
you memory requirements once in a while.  If you decided on level 5 trie,
adding 1100 signatures might not even make a difference.  But as a rule
of thumb, when you upgrade, you should examine your database to see
if you need to adjust number of levels to get best performance...

> 
> Sorry, but your patch only brake the things. It removes the important
> condition on minimal signature length.
> 

Yup, it does remove this condition.  But I would rather call it a limitation.

> 
> No, you're not right. I've applied your patch and the Magistr virus in
> that file was not detected. I hope someone following this thread can
> check it(at least I will ask other ClamAV developers) and confirm my
> test.
> 
> > Pointing out my mistakes is fine, making baseless statements is not.
> 
> OK, I will describe you the problem: 
> 
> The Magistr signature is:
> 
> W32/Magistr.B=0000??2e??????????0000ed????0000????0000????0000????00000
> 000000000??0000*e804720000
> 
> In cl_hex2str() [libclamav/str.c, lines 63-64] the question marks ?? are
> translated into CLI_IGN. Now with the level _higher_ then 2 in
> cli_addpatt() CLI_IGN goes into the trie "as a node". Because it's not
> possible to match CLI_IGN while travelling the trie, the Magistr pattern
> will never be matched... That's why I haven't read your last attachment.
> 

Point taken -- it's a bug in my patch.
But, you know what they say in the movies: "Never say never" :)
So, a new patch is attached which correctly identifies magistr.b w/out
requirement to have at most 2 levels.


> 
> -------------------------------------------------------
> This SF.net email is sponsored by: VM Ware
> With VMware you can run multiple operating systems on a single machine.
> WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines
> at the same time. Free trial click here:http://www.vmware.com/wl/offer/358/0
> _______________________________________________
> Clamav-devel mailing list
> [EMAIL PROTECTED]
> https://lists.sourceforge.net/lists/listinfo/clamav-devel

-- 
  Eugene Miretskiy <[EMAIL PROTECTED]>
  INVISION.COM, INC.  (631) 543-1000
  www.invision.net  /  www.longisland.com 
Only in clamav-0.60.new: autom4te.cache
diff -ru -x target.h -x aclocal.m4 -x Makefile.in -x configure 
clamav-0.60/configure.in clamav-0.60.new/configure.in
--- clamav-0.60/configure.in    2003-06-20 23:05:32.000000000 -0400
+++ clamav-0.60.new/configure.in        2003-09-01 21:07:51.000000000 -0400
@@ -176,6 +176,13 @@
 AC_SUBST(CFGDIR)
 AC_DEFINE_UNQUOTED(CONFDIR,"$cfg_dir",)
 
+dnl search tree depth
+AC_ARG_WITH(depth, 
+[  --with-depth=number   number of levels in pattern search tree (default=2).],
+tree_depth=$withval, tree_depth=2)
+
+AC_DEFINE_UNQUOTED(CL_MIN_LENGTH,$tree_depth,)
+
 dnl Do not overwrite the current config file
 AM_CONDITIONAL(INSTALL_CONF, test ! -r "$cfg_dir/clamav.conf")
 
diff -ru -x target.h -x aclocal.m4 -x Makefile.in -x configure 
clamav-0.60/libclamav/clamav.h clamav-0.60.new/libclamav/clamav.h
--- clamav-0.60/libclamav/clamav.h      2000-03-15 20:05:00.000000000 -0500
+++ clamav-0.60.new/libclamav/clamav.h  2003-09-01 21:26:15.000000000 -0400
@@ -30,7 +30,10 @@
  
 
 #define CL_NUM_CHILDS 256
-#define CL_MIN_LENGTH 2
+
+#ifndef CL_MIN_LENGTH
+  #define CL_MIN_LENGTH 2
+#endif
 
 #define CL_COUNT_PRECISION 4096
 
@@ -71,16 +74,14 @@
 };
 
 struct cl_node {
-    char islast;
+    unsigned short int level;
     struct patt *list;
     struct cl_node *trans[CL_NUM_CHILDS], *fail;
 
-    /* FIXME: these variables are only used in the root node */
-    unsigned int maxpatlen, partsigs;
-    unsigned int nodes;
-    struct cl_node **nodetable;
 };
 
+extern unsigned int maxpatlen, partsigs;
+
 struct cl_limits {
     int maxreclevel;
     int maxfiles;
diff -ru -x target.h -x aclocal.m4 -x Makefile.in -x configure 
clamav-0.60/libclamav/matcher.c clamav-0.60.new/libclamav/matcher.c
--- clamav-0.60/libclamav/matcher.c     2000-01-09 17:15:00.000000000 -0500
+++ clamav-0.60.new/libclamav/matcher.c 2003-09-01 21:26:31.000000000 -0400
@@ -32,18 +32,17 @@
 #include "unrarlib.h"
 #include "defaults.h"
 
+struct cl_node **nodetable;
+unsigned int nodes = 0;
+
 int cli_addpatt(struct cl_node *root, struct patt *pattern)
 {
        struct cl_node *pos, *next;
        int i;
 
-    if(pattern->length < CL_MIN_LENGTH) {
-       return CL_EPATSHORT;
-    }
-
     pos = root;
 
-    for(i = 0; i < CL_MIN_LENGTH; i++) {
+    for(i = 0; i < CL_MIN_LENGTH && i < pattern->length && pattern->pattern[i] != 
CLI_IGN; i++) {
        next = pos->trans[((unsigned char) pattern->pattern[i]) & 0xff]; 
 
        if(!next) {
@@ -51,9 +50,9 @@
            if(!next)
                return CL_EMEM;
 
-           root->nodes++;
-           root->nodetable = (struct cl_node **) realloc(root->nodetable, 
(root->nodes) * sizeof(struct cl_node *));
-           root->nodetable[root->nodes - 1] = next;
+           nodes++;
+           nodetable = (struct cl_node **) realloc(nodetable, nodes * sizeof(struct 
cl_node *));
+           nodetable[nodes - 1] = next;
 
            pos->trans[((unsigned char) pattern->pattern[i]) & 0xff] = next;
        }
@@ -61,7 +60,7 @@
        pos = next;
     }
 
-    pos->islast = 1;
+    pos->level = i;
 
     pattern->next = pos->list;
     pos->list = pattern;
@@ -117,9 +116,6 @@
     cli_enqueue(&bfs, root);
 
     while((node = cli_dequeue(&bfs))) {
-       if(node->islast)
-           continue;
-
        for(i = 0; i < CL_NUM_CHILDS; i++) {
            child = node->trans[i];
            if(!child) {
@@ -164,12 +160,12 @@
 {
        int i;
 
-    for(i = 0; i < root->nodes; i++) {
-       cli_freepatt(root->nodetable[i]->list);
-       free(root->nodetable[i]);
+    for(i = 0; i < nodes; i++) {
+       cli_freepatt(nodetable[i]->list);
+       free(nodetable[i]);
     }
 
-    free(root->nodetable);
+    free(nodetable);
     free(root);
 }
 
@@ -181,17 +177,17 @@
 
     current = (struct cl_node *) root;
 
-    partcnt = (int *) cli_calloc(root->partsigs + 1, sizeof(int));
+    partcnt = (int *) cli_calloc(partsigs + 1, sizeof(int));
 
     for(i = 0; i < length; i++)  {
        current = current->trans[(unsigned char) buffer[i] & 0xff];
 
-       if(current->islast) {
-           position = i - CL_MIN_LENGTH + 1;
-
+       if(current->list) {
+           position = i - current->level + 1;
            pt = current->list;
+
            while(pt) {
-               if(cli_findpos(buffer, position, length, pt)) {
+               if(cli_findpos(buffer, position, current->level, length, pt)) {
                    if(pt->sigid) { /* it's a partial signature */
                        if(partcnt[pt->sigid] + 1 == pt->partno) {
                            if(++partcnt[pt->sigid] == pt->parts) { /* last */
@@ -220,14 +216,14 @@
     return CL_CLEAN;
 }
 
-int cli_findpos(const char *buffer, int offset, int length, const struct patt 
*pattern)
+int cli_findpos(const char *buffer, int offset, unsigned short int pattoffset, int 
length, const struct patt *pattern)
 {
-       int bufferpos = offset + CL_MIN_LENGTH;
+       int bufferpos = offset + pattoffset;
        int postfixend = offset + length;
        int i;
 
 
-    for(i = CL_MIN_LENGTH; i < pattern->length; i++) {
+    for(i = pattoffset; i < pattern->length; i++) {
 
        bufferpos %= length;
 
diff -ru -x target.h -x aclocal.m4 -x Makefile.in -x configure 
clamav-0.60/libclamav/matcher.h clamav-0.60.new/libclamav/matcher.h
--- clamav-0.60/libclamav/matcher.h     2002-10-05 18:00:00.000000000 -0400
+++ clamav-0.60.new/libclamav/matcher.h 2003-09-01 21:11:07.000000000 -0400
@@ -30,6 +30,6 @@
 struct nodelist *cli_bfsadd(struct nodelist *bfs, struct cl_node *n);
 void cli_failtrans(struct cl_node *root);
 void cli_fasttrie(struct cl_node *n, struct cl_node *root);
-int cli_findpos(const char *buffer, int offset, int length, const struct patt 
*pattern);
+int cli_findpos(const char *buffer, int offset, unsigned short int pattoffset, int 
length, const struct patt *pattern);
 
 #endif
diff -ru -x target.h -x aclocal.m4 -x Makefile.in -x configure 
clamav-0.60/libclamav/readdb.c clamav-0.60.new/libclamav/readdb.c
--- clamav-0.60/libclamav/readdb.c      2003-06-20 13:56:17.000000000 -0400
+++ clamav-0.60.new/libclamav/readdb.c  2003-09-01 21:24:48.000000000 -0400
@@ -34,6 +34,9 @@
 #include "str.h"
 #include "defaults.h"
 
+unsigned int maxpatlen = 0;
+unsigned int partsigs = 0;
+
 int cli_parse_add(struct cl_node *root, const char *virname, const char *hexstr, int 
sigid, int parts, int partno)
 {
        struct patt *new;
@@ -51,8 +54,8 @@
 
     new->length = strlen(hexstr) / 2;
 
-    if(new->length > root->maxpatlen)
-       root->maxpatlen = new->length;
+    if(new->length > maxpatlen)
+       maxpatlen = new->length;
 
     if((new->pattern = cl_hex2str(hexstr)) == NULL) {
        free(new);
@@ -117,11 +120,11 @@
            *root = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node));
            if(!*root)
                return CL_EMEM;
-           (*root)->maxpatlen = 0;
+           maxpatlen = 0;
        }
 
        if(strchr(pt, '*')) { /* new type signature */
-           (*root)->partsigs++;
+           partsigs++;
            sigid++;
            parts = 0;
            for(i = 0; i < strlen(pt); i++)
diff -ru -x target.h -x aclocal.m4 -x Makefile.in -x configure 
clamav-0.60/libclamav/scanners.c clamav-0.60.new/libclamav/scanners.c
--- clamav-0.60/libclamav/scanners.c    2003-06-19 21:37:31.000000000 -0400
+++ clamav-0.60.new/libclamav/scanners.c        2003-09-01 21:25:10.000000000 -0400
@@ -67,14 +67,14 @@
 
 
     /* prepare the buffer */
-    buffsize = root->maxpatlen + BUFFSIZE;
+    buffsize = maxpatlen + BUFFSIZE;
     if(!(buffer = (char *) cli_calloc(buffsize, sizeof(char))))
        return CL_EMEM;
 
     buff = buffer;
-    buff += root->maxpatlen; /* pointer to read data block */
-    endbl = buff + BUFFSIZE - root->maxpatlen; /* pointer to the last block
-                                               * length of root->maxpatlen
+    buff += maxpatlen; /* pointer to read data block */
+    endbl = buff + BUFFSIZE - maxpatlen; /* pointer to the last block
+                                               * length of maxpatlen
                                                */
 
     pt= buff;
@@ -94,7 +94,7 @@
        }
 
        if(bytes == BUFFSIZE)
-           memmove(buffer, endbl, root->maxpatlen);
+           memmove(buffer, endbl, maxpatlen);
 
         pt = buffer;
         length=buffsize;

Attachment: pgp00000.pgp
Description: PGP signature

Reply via email to