Browse code

libclamav/matcher-ac.c: add support for returning multiple matches in cli_ac_scanbuff()

git-svn: trunk@4017

Tomasz Kojm authored on 2008/07/29 18:04:28
Showing 6 changed files
... ...
@@ -1,3 +1,8 @@
1
+Tue Jul 29 10:47:23 CEST 2008 (tk)
2
+----------------------------------
3
+  * libclamav/matcher-ac.c: add support for returning multiple matches in
4
+			    cli_ac_scanbuff()
5
+
1 6
 Tue Jul 29 10:29:54 EEST 2008 (edwin)
2 7
 -------------------------------------
3 8
   * configure.in: check for <sys/select.h> before <sys/types.h> (bb #452)
... ...
@@ -166,7 +166,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine)
166 166
 	if(cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, AC_DEFAULT_TRACKLEN))
167 167
 	    return ret;
168 168
 
169
-	sret = cli_ac_scanbuff(buff, bread, NULL, NULL, engine->root[0], &mdata, 0, ret, desc, NULL, AC_SCAN_FT, NULL);
169
+	sret = cli_ac_scanbuff(buff, bread, NULL, NULL, NULL, engine->root[0], &mdata, 0, ret, desc, NULL, AC_SCAN_FT, NULL);
170 170
 
171 171
 	cli_ac_freedata(&mdata);
172 172
 
... ...
@@ -178,7 +178,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine)
178 178
 
179 179
 	    decoded = (unsigned char *) cli_utf16toascii((char *) buff, bread);
180 180
 	    if(decoded) {
181
-		sret = cli_ac_scanbuff(decoded, strlen((char *) decoded), NULL, NULL,  engine->root[0], &mdata, 0, CL_TYPE_TEXT_ASCII, desc, NULL, AC_SCAN_FT, NULL);
181
+		sret = cli_ac_scanbuff(decoded, strlen((char *) decoded), NULL, NULL, NULL,  engine->root[0], &mdata, 0, CL_TYPE_TEXT_ASCII, desc, NULL, AC_SCAN_FT, NULL);
182 182
 		free(decoded);
183 183
 		if(sret == CL_TYPE_HTML)
184 184
 		    ret = CL_TYPE_HTML_UTF16;
... ...
@@ -212,7 +212,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine)
212 212
 					    return ret;
213 213
 
214 214
 				    if(out_area.length > 0) {
215
-					    sret = cli_ac_scanbuff(decodedbuff, out_area.length, NULL, NULL, engine->root[0], &mdata, 0, 0, desc, NULL, AC_SCAN_FT, NULL); /* FIXME: can we use CL_TYPE_TEXT_ASCII instead of 0? */
215
+					    sret = cli_ac_scanbuff(decodedbuff, out_area.length, NULL, NULL, NULL, engine->root[0], &mdata, 0, 0, desc, NULL, AC_SCAN_FT, NULL); /* FIXME: can we use CL_TYPE_TEXT_ASCII instead of 0? */
216 216
 					    if(sret == CL_TYPE_HTML) {
217 217
 						    cli_dbgmsg("cli_filetype2: detected HTML signature in Unicode file\n");
218 218
 						    /* htmlnorm is able to handle any unicode now, since it skips null chars */
... ...
@@ -832,7 +832,7 @@ inline static int ac_addtype(struct cli_matched_type **list, cli_file_t type, of
832 832
     return CL_SUCCESS;
833 833
 }
834 834
 
835
-int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx)
835
+int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx)
836 836
 {
837 837
 	struct cli_ac_node *current;
838 838
 	struct cli_ac_patt *patt, *pt;
... ...
@@ -842,6 +842,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
842 842
 	uint8_t found;
843 843
 	struct cli_target_info info;
844 844
 	int type = CL_CLEAN;
845
+	struct cli_ac_result *newres;
845 846
 
846 847
 
847 848
     if(!root->ac_root)
... ...
@@ -895,6 +896,8 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
895 895
 				mdata->offmatrix[pt->sigid - 1] = cli_malloc(pt->parts * sizeof(int32_t *));
896 896
 				if(!mdata->offmatrix[pt->sigid - 1]) {
897 897
 				    cli_errmsg("cli_ac_scanbuff: Can't allocate memory for mdata->offmatrix[%u]\n", pt->sigid - 1);
898
+				    if(info.exeinfo.section)
899
+					free(info.exeinfo.section);
898 900
 				    return CL_EMEM;
899 901
 				}
900 902
 
... ...
@@ -903,6 +906,8 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
903 903
 				    cli_errmsg("cli_ac_scanbuff: Can't allocate memory for mdata->offmatrix[%u][0]\n", pt->sigid - 1);
904 904
 				    free(mdata->offmatrix[pt->sigid - 1]);
905 905
 				    mdata->offmatrix[pt->sigid - 1] = NULL;
906
+				    if(info.exeinfo.section)
907
+					free(info.exeinfo.section);
906 908
 				    return CL_EMEM;
907 909
 				}
908 910
 				memset(mdata->offmatrix[pt->sigid - 1][0], -1, pt->parts * (AC_DEFAULT_TRACKLEN + 1) * sizeof(int32_t));
... ...
@@ -974,15 +979,31 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
974 974
 					continue;
975 975
 				    }
976 976
 
977
-				    if(virname)
978
-					*virname = pt->virname;
979
-				    if(customdata)
980
-					*customdata = pt->customdata;
977
+				    if(res) {
978
+					newres = (struct cli_ac_result *) malloc(sizeof(struct cli_ac_result));
979
+					if(!newres) {
980
+					    if(info.exeinfo.section)
981
+						free(info.exeinfo.section);
982
+					    return CL_EMEM;
983
+					}
984
+					newres->virname = pt->virname;
985
+					newres->customdata = pt->customdata;
986
+					newres->next = *res;
987
+					*res = newres;
981 988
 
982
-				    if(info.exeinfo.section)
983
-					free(info.exeinfo.section);
989
+					pt = pt->next;
990
+					continue;
991
+				    } else {
992
+					if(virname)
993
+					    *virname = pt->virname;
994
+					if(customdata)
995
+					    *customdata = pt->customdata;
984 996
 
985
-				    return CL_VIRUS;
997
+					if(info.exeinfo.section)
998
+					    free(info.exeinfo.section);
999
+
1000
+					return CL_VIRUS;
1001
+				    }
986 1002
 				}
987 1003
 			    }
988 1004
 
... ...
@@ -1013,14 +1034,31 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
1013 1013
 				    continue;
1014 1014
 				}
1015 1015
 
1016
-				if(virname)
1017
-				    *virname = pt->virname;
1018
-				if(customdata)
1019
-				    *customdata = pt->customdata;
1016
+				if(res) {
1017
+				    newres = (struct cli_ac_result *) malloc(sizeof(struct cli_ac_result));
1018
+				    if(!newres) {
1019
+					if(info.exeinfo.section)
1020
+					    free(info.exeinfo.section);
1021
+					return CL_EMEM;
1022
+				    }
1023
+				    newres->virname = pt->virname;
1024
+				    newres->customdata = pt->customdata;
1025
+				    newres->next = *res;
1026
+				    *res = newres;
1027
+
1028
+				    pt = pt->next;
1029
+				    continue;
1030
+				} else {
1031
+				    if(virname)
1032
+					*virname = pt->virname;
1033
+				    if(customdata)
1034
+					*customdata = pt->customdata;
1035
+
1036
+				    if(info.exeinfo.section)
1037
+					free(info.exeinfo.section);
1020 1038
 
1021
-				if(info.exeinfo.section)
1022
-				    free(info.exeinfo.section);
1023
-				return CL_VIRUS;
1039
+				    return CL_VIRUS;
1040
+				}
1024 1041
 			    }
1025 1042
 			}
1026 1043
 			pt = pt->next_same;
... ...
@@ -72,13 +72,19 @@ struct cli_ac_node {
72 72
     uint8_t leaf, final;
73 73
 };
74 74
 
75
+struct cli_ac_result {
76
+    const char *virname;
77
+    void *customdata;
78
+    struct cli_ac_result *next;
79
+};
80
+
75 81
 #include "matcher.h"
76 82
 
77 83
 int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern);
78 84
 int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs, uint8_t tracklen);
79 85
 int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigned int *cnt, uint64_t *ids, unsigned int parse_only);
80 86
 void cli_ac_freedata(struct cli_ac_data *data);
81
-int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx);
87
+int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, int fd, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx);
82 88
 int cli_ac_buildtrie(struct cli_matcher *root);
83 89
 int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth);
84 90
 void cli_ac_free(struct cli_matcher *root);
... ...
@@ -76,7 +76,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli
76 76
 	    return ret;
77 77
 
78 78
 	if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, 0, ftype, -1)) != CL_VIRUS)
79
-	    ret = cli_ac_scanbuff(buffer, length, virname, NULL, troot, &mdata, 0, ftype, -1, NULL, AC_SCAN_VIR, NULL);
79
+	    ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, troot, &mdata, 0, ftype, -1, NULL, AC_SCAN_VIR, NULL);
80 80
 
81 81
 	cli_ac_freedata(&mdata);
82 82
 
... ...
@@ -88,7 +88,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli
88 88
 	return ret;
89 89
 
90 90
     if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, 0, ftype, -1)) != CL_VIRUS)
91
-	ret = cli_ac_scanbuff(buffer, length, virname, NULL, groot, &mdata, 0, ftype, -1, NULL, AC_SCAN_VIR, NULL);
91
+	ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, groot, &mdata, 0, ftype, -1, NULL, AC_SCAN_VIR, NULL);
92 92
 
93 93
     cli_ac_freedata(&mdata);
94 94
 
... ...
@@ -326,7 +326,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
326 326
 
327 327
 	if(troot) {
328 328
 	    if(troot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, troot, offset, ftype, desc)) != CL_VIRUS)
329
-		ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, troot, &tdata, offset, ftype, desc, ftoffset, acmode, NULL);
329
+		ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, troot, &tdata, offset, ftype, desc, ftoffset, acmode, NULL);
330 330
 
331 331
 	    if(ret == CL_VIRUS) {
332 332
 		free(buffer);
... ...
@@ -344,7 +344,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
344 344
 
345 345
 	if(!ftonly) {
346 346
 	    if(groot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, groot, offset, ftype, desc)) != CL_VIRUS)
347
-		ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, groot, &gdata, offset, ftype, desc, ftoffset, acmode, NULL);
347
+		ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, groot, &gdata, offset, ftype, desc, ftoffset, acmode, NULL);
348 348
 
349 349
 	    if(ret == CL_VIRUS) {
350 350
 		free(buffer);
... ...
@@ -287,7 +287,7 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di
287 287
 			return 0;
288 288
 		}
289 289
 
290
-		rc = cli_ac_scanbuff((const unsigned char*)bufrev,buffer_len, NULL, &regex, &matcher->suffixes,&mdata,0,0,-1,NULL,AC_SCAN_VIR,NULL);
290
+		rc = cli_ac_scanbuff((const unsigned char*)bufrev,buffer_len, NULL, &regex, NULL, &matcher->suffixes,&mdata,0,0,-1,NULL,AC_SCAN_VIR,NULL);
291 291
 		free(bufrev);
292 292
 		cli_ac_freedata(&mdata);
293 293