Browse code

libclamav/matcher-ac.c: improve handling of signature offsets

Tomasz Kojm authored on 2009/08/27 06:39:35
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Wed Aug 26 23:37:04 CEST 2009 (tk)
2
+----------------------------------
3
+ * libclamav/matcher-ac.c: improve handling of signature offsets
4
+
1 5
 Mon Aug 24 22:09:12 CEST 2009 (tk)
2 6
 ----------------------------------
3 7
  * libclamav: improve handling of PDF files (bb#1682)
... ...
@@ -26,6 +26,7 @@
26 26
 #include <string.h>
27 27
 #include <stdlib.h>
28 28
 #include <ctype.h>
29
+#include <sys/stat.h>
29 30
 
30 31
 #include <assert.h>
31 32
 #ifdef	HAVE_UNISTD_H
... ...
@@ -835,8 +836,15 @@ int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int
835 835
 	unsigned int i;
836 836
 	struct cli_ac_patt *patt;
837 837
 	struct cli_target_info info;
838
+	struct stat sb;
838 839
 
839 840
     memset(&info, 0, sizeof(info));
841
+    if(fstat(fd, &sb) == -1) {
842
+	cli_errmsg("cli_ac_caloff: fstat(%d) failed\n", fd);
843
+	return CL_ESTAT;
844
+    }
845
+    info.fsize = sb.st_size;
846
+
840 847
     for(i = 0; i < root->ac_reloff_num; i++) {
841 848
 	patt = root->ac_reloff[i];
842 849
 	if(fd == -1) {
... ...
@@ -846,6 +854,8 @@ int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int
846 846
 	    if(info.exeinfo.section)
847 847
 		free(info.exeinfo.section);
848 848
 	    return ret;
849
+	} else if(data->offset[patt->offset_min] + patt->length > info.fsize) {
850
+	    data->offset[patt->offset_min] = CLI_OFF_NONE;
849 851
 	}
850 852
     }
851 853
     if(info.exeinfo.section)
... ...
@@ -946,39 +956,37 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
946 946
 	    patt = current->list;
947 947
 	    while(patt) {
948 948
 		bp = i + 1 - patt->depth;
949
-		pt = patt;
950
-	 	/*
951
-		while(pt) {
952
-		    if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) {
953
-			pt = pt->next_same;
954
-			continue;
955
-		    }
956
-		    if(pt->offset_min == CLI_OFF_NONE) {
957
-			pt = pt->next_same;
949
+		if(!patt->next_same && (patt->offset_min != CLI_OFF_ANY) && (!patt->sigid || patt->partno == 1)) {
950
+		    if(patt->offset_min == CLI_OFF_NONE) {
951
+			patt = patt->next;
958 952
 			continue;
959 953
 		    }
960
-		    realoff = offset + bp - pt->prefix_length;
961
-		    if(pt->offset_min != CLI_OFF_ANY && (!pt->sigid || pt->partno == 1)) {
962
-			if(pt->offset_max > realoff || pt->offset_min < realoff) {
963
-			    pt = pt->next_same;
954
+		    realoff = offset + bp - patt->prefix_length;
955
+		    if(patt->offdata[0] == CLI_OFF_ABSOLUTE) {
956
+			if(patt->offset_max < realoff || patt->offset_min > realoff) {
957
+			    patt = patt->next;
958
+			    continue;
959
+			}
960
+		    } else {
961
+			if(mdata->offset[patt->offset_min] == CLI_OFF_NONE || mdata->offset[patt->offset_max] < realoff || mdata->offset[patt->offset_min] > realoff) {
962
+			    patt = patt->next;
964 963
 			    continue;
965 964
 			}
966 965
 		    }
967
-		    break;
968 966
 		}
969
-		*/
970
-		if(pt && ac_findmatch(buffer, bp, length, patt, &matchend)) {
967
+		pt = patt;
968
+		if(ac_findmatch(buffer, bp, length, patt, &matchend)) {
971 969
 		    while(pt) {
972 970
 			if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) {
973 971
 			    pt = pt->next_same;
974 972
 			    continue;
975 973
 			}
976
-			if(pt->offset_min == CLI_OFF_NONE) {
977
-			    pt = pt->next_same;
978
-			    continue;
979
-			}
980 974
 			realoff = offset + bp - pt->prefix_length;
981 975
 			if(pt->offset_min != CLI_OFF_ANY && (!pt->sigid || pt->partno == 1)) {
976
+			    if(pt->offset_min == CLI_OFF_NONE) {
977
+				pt = pt->next_same;
978
+				continue;
979
+			    }
982 980
 			    if(pt->offdata[0] == CLI_OFF_ABSOLUTE) {
983 981
 				if(pt->offset_max < realoff || pt->offset_min > realoff) {
984 982
 				    pt = pt->next_same;