Browse code

libclamav: call cli_checkfp() whenever possible/makes sense (bb#1558)

git-svn: trunk@5053

Tomasz Kojm authored on 2009/04/23 22:24:21
Showing 9 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Apr 23 15:23:02 CEST 2009 (tk)
2
+----------------------------------
3
+ * libclamav: call cli_checkfp() whenever possible/makes sense (bb#1558)
4
+
1 5
 Wed Apr 22 14:24:03 EEST 2009 (edwin)
2 6
 -------------------------------------
3 7
  * libclamav/special.c: tune sensitivity of Trojan.Swizzor.Gen
... ...
@@ -37,6 +37,7 @@
37 37
 #include "elf.h"
38 38
 #include "clamav.h"
39 39
 #include "execs.h"
40
+#include "matcher.h"
40 41
 
41 42
 static inline uint16_t EC16(uint16_t v, uint8_t c)
42 43
 {
... ...
@@ -195,7 +196,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
195 195
         if(DETECT_BROKEN) {
196 196
 	    if(ctx->virname)
197 197
 		*ctx->virname = "Broken.Executable";
198
-            return CL_VIRUS;
198
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
199 199
         }
200 200
 	return CL_EFORMAT;
201 201
     }
... ...
@@ -208,7 +209,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
208 208
 	    if(DETECT_BROKEN) {
209 209
 		if(ctx->virname)
210 210
 		    *ctx->virname = "Broken.Executable";
211
-		return CL_VIRUS;
211
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
212 212
 	    }
213 213
 	    return CL_EFORMAT;
214 214
 	}
... ...
@@ -219,7 +220,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
219 219
 	    if(DETECT_BROKEN) {
220 220
 		if(ctx->virname)
221 221
 		    *ctx->virname = "Broken.Executable";
222
-		return CL_VIRUS;
222
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
223 223
 	    }
224 224
 	    return CL_CLEAN;
225 225
 	}
... ...
@@ -241,7 +242,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
241 241
 		if(DETECT_BROKEN) {
242 242
 		    if(ctx->virname)
243 243
 			*ctx->virname = "Broken.Executable";
244
-		    return CL_VIRUS;
244
+		    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
245 245
 		}
246 246
 		return CL_CLEAN;
247 247
 	    }
... ...
@@ -262,7 +263,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
262 262
 	    if(DETECT_BROKEN) {
263 263
 		if(ctx->virname)
264 264
 		    *ctx->virname = "Broken.Executable";
265
-		return CL_VIRUS;
265
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
266 266
 	    }
267 267
 	    return CL_EFORMAT;
268 268
 	}
... ...
@@ -279,7 +280,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
279 279
         if(DETECT_BROKEN) {
280 280
 	    if(ctx->virname)
281 281
 		*ctx->virname = "Broken.Executable";
282
-            return CL_VIRUS;
282
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
283 283
         }
284 284
 	return CL_EFORMAT;
285 285
     }
... ...
@@ -290,7 +291,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
290 290
         if(DETECT_BROKEN) {
291 291
 	    if(ctx->virname)
292 292
 		*ctx->virname = "Broken.Executable";
293
-            return CL_VIRUS;
293
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
294 294
         }
295 295
 	return CL_EFORMAT;
296 296
     }
... ...
@@ -302,7 +303,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
302 302
         if(DETECT_BROKEN) {
303 303
 	    if(ctx->virname)
304 304
 		*ctx->virname = "Broken.Executable";
305
-            return CL_VIRUS;
305
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
306 306
         }
307 307
 	return CL_CLEAN;
308 308
     }
... ...
@@ -324,7 +325,7 @@ int cli_scanelf(int desc, cli_ctx *ctx)
324 324
             if(DETECT_BROKEN) {
325 325
                 if(ctx->virname)
326 326
                     *ctx->virname = "Broken.Executable";
327
-                return CL_VIRUS;
327
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
328 328
             }
329 329
             return CL_CLEAN;
330 330
         }
... ...
@@ -204,26 +204,37 @@ off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_f
204 204
     return 0;
205 205
 }
206 206
 
207
-static int cli_checkfp(int fd, const struct cl_engine *engine)
207
+int cli_checkfp(int fd, cli_ctx *ctx)
208 208
 {
209 209
 	unsigned char *digest;
210 210
 	const char *virname;
211
+	off_t pos;
211 212
 
212 213
 
213
-    if(engine->md5_fp) {
214
+    if((pos = lseek(fd, 0, SEEK_CUR)) == -1) {
215
+	cli_errmsg("cli_checkfp(): lseek() failed\n");
216
+	return 0;
217
+    }
218
+
219
+    lseek(fd, 0, SEEK_SET);
220
+
221
+    if(ctx->engine->md5_fp) {
214 222
 	if(!(digest = cli_md5digest(fd))) {
215 223
 	    cli_errmsg("cli_checkfp(): Can't generate MD5 checksum\n");
224
+	    lseek(fd, pos, SEEK_SET);
216 225
 	    return 0;
217 226
 	}
218 227
 
219
-	if(cli_bm_scanbuff(digest, 16, &virname, engine->md5_fp, 0, 0, -1) == CL_VIRUS) {
220
-	    cli_dbgmsg("Eliminated false positive match (fp sig: %s)\n", virname);
228
+	if(cli_bm_scanbuff(digest, 16, &virname, ctx->engine->md5_fp, 0, 0, -1) == CL_VIRUS) {
229
+	    cli_dbgmsg("cli_checkfp(): Found false positive detection (fp sig: %s)\n", virname);
221 230
 	    free(digest);
231
+	    lseek(fd, pos, SEEK_SET);
222 232
 	    return 1;
223 233
 	}
224 234
 	free(digest);
225 235
     }
226 236
 
237
+    lseek(fd, pos, SEEK_SET);
227 238
     return 0;
228 239
 }
229 240
 
... ...
@@ -340,8 +351,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
340 340
 		    cli_ac_freedata(&gdata);
341 341
 		cli_ac_freedata(&tdata);
342 342
 
343
-		lseek(desc, 0, SEEK_SET);
344
-		if(cli_checkfp(desc, ctx->engine))
343
+		if(cli_checkfp(desc, ctx))
345 344
 		    return CL_CLEAN;
346 345
 		else
347 346
 		    return CL_VIRUS;
... ...
@@ -357,8 +367,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
357 357
 		cli_ac_freedata(&gdata);
358 358
 		if(troot)
359 359
 		    cli_ac_freedata(&tdata);
360
-		lseek(desc, 0, SEEK_SET);
361
-		if(cli_checkfp(desc, ctx->engine))
360
+		if(cli_checkfp(desc, ctx))
362 361
 		    return CL_CLEAN;
363 362
 		else
364 363
 		    return CL_VIRUS;
... ...
@@ -420,7 +429,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
420 420
 
421 421
     if(ret == CL_VIRUS) {
422 422
 	lseek(desc, 0, SEEK_SET);
423
-	if(cli_checkfp(desc, ctx->engine))
423
+	if(cli_checkfp(desc, ctx))
424 424
 	    return CL_CLEAN;
425 425
 	else
426 426
 	    return CL_VIRUS;
... ...
@@ -131,4 +131,6 @@ int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct
131 131
 
132 132
 off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_file_t ftype, int *ret, unsigned int *maxshift);
133 133
 
134
+int cli_checkfp(int fd, cli_ctx *ctx);
135
+
134 136
 #endif
... ...
@@ -472,7 +472,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
472 472
 	if(DETECT_BROKEN) {
473 473
 	    if(ctx->virname)
474 474
 		*ctx->virname = "Broken.Executable";
475
-	    return CL_VIRUS;
475
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
476 476
 	}
477 477
 	return CL_CLEAN;
478 478
     }
... ...
@@ -608,7 +608,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
608 608
 	if(DETECT_BROKEN) {
609 609
 	    if(ctx->virname)
610 610
 		*ctx->virname = "Broken.Executable";
611
-	    return CL_VIRUS;
611
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
612 612
 	}
613 613
 	if(nsections)
614 614
 	    cli_warnmsg("PE file contains %d sections\n", nsections);
... ...
@@ -628,7 +628,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
628 628
 	if(DETECT_BROKEN) {
629 629
 	    if(ctx->virname)
630 630
 	        *ctx->virname = "Broken.Executable";
631
-	    return CL_VIRUS;
631
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
632 632
 	}
633 633
 	return CL_CLEAN;
634 634
     }
... ...
@@ -638,7 +638,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
638 638
 	if(DETECT_BROKEN) {
639 639
 	    if(ctx->virname)
640 640
 	        *ctx->virname = "Broken.Executable";
641
-	    return CL_VIRUS;
641
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
642 642
 	}
643 643
 	return CL_CLEAN;
644 644
     }
... ...
@@ -651,7 +651,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
651 651
 	    if(DETECT_BROKEN) {
652 652
 	        if(ctx->virname)
653 653
 		    *ctx->virname = "Broken.Executable";
654
-		return CL_VIRUS;
654
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
655 655
 	    }
656 656
 	    return CL_CLEAN;
657 657
 	}
... ...
@@ -667,7 +667,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
667 667
 	    if(DETECT_BROKEN) {
668 668
 	        if(ctx->virname)
669 669
 		    *ctx->virname = "Broken.Executable";
670
-		return CL_VIRUS;
670
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
671 671
 	    }
672 672
 	    cli_dbgmsg("9x compatibility mode\n");
673 673
 	}
... ...
@@ -709,7 +709,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
709 709
 	    if(DETECT_BROKEN) {
710 710
 	        if(ctx->virname)
711 711
 		    *ctx->virname = "Broken.Executable";
712
-		return CL_VIRUS;
712
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
713 713
 	    }
714 714
 	    return CL_CLEAN;
715 715
 	}
... ...
@@ -790,14 +790,14 @@ int cli_scanpe(int desc, cli_ctx *ctx)
790 790
         cli_dbgmsg("Bad virtual alignemnt\n");
791 791
         if(ctx->virname)
792 792
 	    *ctx->virname = "Broken.Executable";
793
-	return CL_VIRUS;
793
+	return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
794 794
     }
795 795
 
796 796
     if (DETECT_BROKEN && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) {
797 797
         cli_dbgmsg("Bad file alignemnt\n");
798 798
 	if(ctx->virname)
799 799
 	    *ctx->virname = "Broken.Executable";
800
-	return CL_VIRUS;
800
+	return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
801 801
     }
802 802
 
803 803
     if(fstat(desc, &sb) == -1) {
... ...
@@ -833,7 +833,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
833 833
 	if(DETECT_BROKEN) {
834 834
 	    if(ctx->virname)
835 835
 		*ctx->virname = "Broken.Executable";
836
-	    return CL_VIRUS;
836
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
837 837
 	}
838 838
 	return CL_CLEAN;
839 839
     }
... ...
@@ -902,7 +902,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
902 902
 	        *ctx->virname = "Broken.Executable";
903 903
 	    free(section_hdr);
904 904
 	    free(exe_sections);
905
-	    return CL_VIRUS;
905
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
906 906
 	}
907 907
 
908 908
 	if (exe_sections[i].rsz) { /* Don't bother with virtual only sections */
... ...
@@ -913,7 +913,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
913 913
 		if(DETECT_BROKEN) {
914 914
 		    if(ctx->virname)
915 915
 		        *ctx->virname = "Broken.Executable";
916
-		    return CL_VIRUS;
916
+		    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
917 917
 		}
918 918
 		return CL_CLEAN; /* no ninjas to see here! move along! */
919 919
 	    }
... ...
@@ -928,16 +928,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
928 928
 		    if(md5_sect->soff[j] == exe_sections[i].rsz) {
929 929
 			unsigned char md5_dig[16];
930 930
 			if(cli_md5sect(desc, &exe_sections[i], md5_dig) && cli_bm_scanbuff(md5_dig, 16, ctx->virname, ctx->engine->md5_mdb, 0, 0, -1) == CL_VIRUS) {
931
-			    /* Since .mdb sigs are not fp-prone, to save
932
-			     * performance we don't call cli_checkfp() here,
933
-			     * just give the possibility of whitelisting
934
-			     * idividual .mdb entries via daily.fp
935
-			     */
936 931
 			    if(cli_bm_scanbuff(md5_dig, 16, NULL, ctx->engine->md5_fp, 0, 0, -1) != CL_VIRUS) {
937 932
 
938 933
 				free(section_hdr);
939 934
 				free(exe_sections);
940
-				return CL_VIRUS;
935
+				return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
941 936
 			    }
942 937
 			}
943 938
 			break;
... ...
@@ -953,7 +948,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
953 953
 	    if(DETECT_BROKEN) {
954 954
 	        if(ctx->virname)
955 955
 		    *ctx->virname = "Broken.Executable";
956
-		return CL_VIRUS;
956
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
957 957
 	    }
958 958
 	    return CL_CLEAN;
959 959
 	}
... ...
@@ -965,7 +960,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
965 965
 		    *ctx->virname = "Broken.Executable";
966 966
 		free(section_hdr);
967 967
 		free(exe_sections);
968
-		return CL_VIRUS;
968
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
969 969
 	    }
970 970
 	    min = exe_sections[i].rva;
971 971
 	    max = exe_sections[i].rva + exe_sections[i].rsz;
... ...
@@ -976,7 +971,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
976 976
 		    *ctx->virname = "Broken.Executable";
977 977
 		free(section_hdr);
978 978
 		free(exe_sections);
979
-		return CL_VIRUS;
979
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
980 980
 	    }
981 981
 	    if(exe_sections[i].rva < min)
982 982
 	        min = exe_sections[i].rva;
... ...
@@ -994,7 +989,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
994 994
 	if(DETECT_BROKEN) {
995 995
 	    if(ctx->virname)
996 996
 		*ctx->virname = "Broken.Executable";
997
-	    return CL_VIRUS;
997
+	    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
998 998
 	}
999 999
 	return CL_CLEAN;
1000 1000
     }
... ...
@@ -1031,7 +1026,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1031 1031
 	    if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) {
1032 1032
 	        *ctx->virname = "W32.Parite.B";
1033 1033
 		free(exe_sections);
1034
-		return CL_VIRUS;
1034
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
1035 1035
 	    }
1036 1036
 	}
1037 1037
     }
... ...
@@ -1114,7 +1109,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1114 1114
 		if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
1115 1115
 		    *ctx->virname = "W32.Kriz";
1116 1116
 		    free(exe_sections);
1117
-		    return CL_VIRUS;
1117
+		    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
1118 1118
 		}
1119 1119
 		cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
1120 1120
 		kzstate++;
... ...
@@ -1141,7 +1136,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1141 1141
 		if(cli_memstr(buff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
1142 1142
 		    *ctx->virname = dam ? "W32.Magistr.A.dam" : "W32.Magistr.A";
1143 1143
 		    free(exe_sections);
1144
-		    return CL_VIRUS;
1144
+		    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
1145 1145
 		} 
1146 1146
 	    }
1147 1147
 
... ...
@@ -1153,7 +1148,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1153 1153
 		if(cli_memstr(buff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
1154 1154
 		    *ctx->virname = dam ? "W32.Magistr.B.dam" : "W32.Magistr.B";
1155 1155
 		    free(exe_sections);
1156
-		    return CL_VIRUS;
1156
+		    return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
1157 1157
 		} 
1158 1158
 	    }
1159 1159
 	}
... ...
@@ -1211,7 +1206,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1211 1211
 		*ctx->virname = "W32.Polipos.A";
1212 1212
 		free(jumps);
1213 1213
 		free(exe_sections);
1214
-		return CL_VIRUS;
1214
+		return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
1215 1215
 	    }
1216 1216
 	}
1217 1217
 	free(jumps);
... ...
@@ -1236,6 +1231,8 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1236 1236
 		    }
1237 1237
 		    if (ret != CL_CLEAN) {
1238 1238
 			    free(exe_sections);
1239
+			    if(ret == CL_VIRUS)
1240
+				return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
1239 1241
 			    return ret;
1240 1242
 		    }
1241 1243
 	    }
... ...
@@ -245,7 +245,7 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx
245 245
 
246 246
     if(mdata) {
247 247
 	*ctx->virname = mdata->virname;
248
-	return CL_VIRUS;	   
248
+	return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
249 249
     }
250 250
 
251 251
     if(DETECT_ENCRYPTED && metadata->encrypted) {
... ...
@@ -1336,13 +1336,15 @@ static int cli_scanscrenc(int desc, cli_ctx *ctx)
1336 1336
     return ret;
1337 1337
 }
1338 1338
 
1339
-static int cli_scanriff(int desc, const char **virname)
1339
+static int cli_scanriff(int desc, cli_ctx *ctx)
1340 1340
 {
1341 1341
 	int ret = CL_CLEAN;
1342 1342
 
1343 1343
     if(cli_check_riff_exploit(desc) == 2) {
1344
-	ret = CL_VIRUS;
1345
-	*virname = "Exploit.W32.MS05-002";
1344
+	if(!cli_checkfp(desc, ctx)) {
1345
+	    ret = CL_VIRUS;
1346
+	    *ctx->virname = "Exploit.W32.MS05-002";
1347
+	}
1346 1348
     }
1347 1349
 
1348 1350
     return ret;
... ...
@@ -1353,8 +1355,10 @@ static int cli_scanjpeg(int desc, cli_ctx *ctx)
1353 1353
 	int ret = CL_CLEAN;
1354 1354
 
1355 1355
     if(cli_check_jpeg_exploit(desc, ctx) == 1) {
1356
-	ret = CL_VIRUS;
1357
-	*ctx->virname = "Exploit.W32.MS04-028";
1356
+	if(!cli_checkfp(desc, ctx)) {
1357
+	    ret = CL_VIRUS;
1358
+	    *ctx->virname = "Exploit.W32.MS04-028";
1359
+	}
1358 1360
     }
1359 1361
 
1360 1362
     return ret;
... ...
@@ -1614,13 +1618,13 @@ static int cli_scan_structured(int desc, cli_ctx *ctx)
1614 1614
     if(cc_count != 0 && cc_count >= ctx->engine->min_cc_count) {
1615 1615
 	cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count);
1616 1616
 	*ctx->virname = "Structured.CreditCardNumber";
1617
-	return CL_VIRUS;
1617
+	return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
1618 1618
     }
1619 1619
 
1620 1620
     if(ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) {
1621 1621
 	cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count);
1622 1622
 	*ctx->virname = "Structured.SSN";
1623
-	return CL_VIRUS;
1623
+	return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
1624 1624
     }
1625 1625
 
1626 1626
     return CL_CLEAN;
... ...
@@ -2025,7 +2029,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2025 2025
 
2026 2026
 	case CL_TYPE_RIFF:
2027 2027
 	    if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_RIFF))
2028
-		ret = cli_scanriff(desc, ctx->virname);
2028
+		ret = cli_scanriff(desc, ctx);
2029 2029
 	    break;
2030 2030
 
2031 2031
 	case CL_TYPE_GRAPHICS:
... ...
@@ -2055,7 +2059,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
2055 2055
 
2056 2056
 	case CL_TYPE_BINARY_DATA:
2057 2057
 	    if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_MYDOOMLOG))
2058
-		ret = cli_check_mydoom_log(desc, ctx->virname);
2058
+		ret = cli_check_mydoom_log(desc, ctx);
2059 2059
 	    break;
2060 2060
 
2061 2061
 	case CL_TYPE_TEXT_ASCII:
... ...
@@ -39,6 +39,7 @@
39 39
 #include "others.h"
40 40
 #include "cltypes.h"
41 41
 #include "special.h"
42
+#include "matcher.h"
42 43
 
43 44
 /* NOTE: Photoshop stores data in BIG ENDIAN format, this is the opposite
44 45
 	to virtually everything else */
... ...
@@ -46,7 +47,7 @@
46 46
 #define special_endian_convert_16(v) be16_to_host(v)
47 47
 #define special_endian_convert_32(v) be32_to_host(v)
48 48
 
49
-int cli_check_mydoom_log(int desc, const char **virname)
49
+int cli_check_mydoom_log(int desc, cli_ctx *ctx)
50 50
 {
51 51
 	int32_t record[8], check;
52 52
 	int i, retval=CL_VIRUS, j;
... ...
@@ -78,8 +79,9 @@ int cli_check_mydoom_log(int desc, const char **virname)
78 78
     if (j < 2) {
79 79
 	retval = CL_CLEAN;
80 80
     } else if (retval==CL_VIRUS) {
81
-	if(virname)
82
-	    *virname = "Worm.Mydoom.M.log";
81
+	if(cli_checkfp(desc, ctx))
82
+	    return CL_CLEAN;
83
+	*ctx->virname = "Worm.Mydoom.M.log";
83 84
     }
84 85
 
85 86
     return retval;
... ...
@@ -33,7 +33,7 @@ struct swizz_stats {
33 33
 	int entries;
34 34
 };
35 35
 
36
-int cli_check_mydoom_log(int desc, const char **virname);
36
+int cli_check_mydoom_log(int desc, cli_ctx *ctx);
37 37
 int cli_check_jpeg_exploit(int fd, cli_ctx *ctx);
38 38
 int cli_check_riff_exploit(int fd);
39 39
 void cli_detect_swizz_str(const unsigned char *str, uint32_t len, struct swizz_stats *stats, int blob);
... ...
@@ -317,7 +317,7 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
317 317
   return ret;
318 318
 }
319 319
 
320
-static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigned int fc, uint8_t *ch, int *ret, cli_ctx *ctx, char *tmpd) {
320
+static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigned int fc, uint8_t *ch, int *ret, cli_ctx *ctx, char *tmpd, int fd) {
321 321
   uint8_t *lh = zip;
322 322
   char name[256];
323 323
   uint32_t csize, usize;
... ...
@@ -364,8 +364,12 @@ static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigne
364 364
 	 )
365 365
 	) meta = meta->next;
366 366
   if(meta) {
367
-    *ctx->virname = meta->virname;
368
-    *ret = CL_VIRUS;
367
+    if(!cli_checkfp(fd, ctx)) {
368
+      *ctx->virname = meta->virname;
369
+      *ret = CL_VIRUS;
370
+    } else
371
+      *ret = CL_CLEAN;
372
+
369 373
     return 0;
370 374
   }
371 375
 
... ...
@@ -427,7 +431,7 @@ static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigne
427 427
 }
428 428
 
429 429
 
430
-static unsigned int chdr(uint8_t *zip, uint32_t coff, uint32_t zsize, unsigned int *fu, unsigned int fc, int *ret, cli_ctx *ctx, char *tmpd) {
430
+static unsigned int chdr(uint8_t *zip, uint32_t coff, uint32_t zsize, unsigned int *fu, unsigned int fc, int *ret, cli_ctx *ctx, char *tmpd, int fd) {
431 431
   uint8_t *ch = &zip[coff];
432 432
   char name[256];
433 433
   int last = 0;
... ...
@@ -465,7 +469,7 @@ static unsigned int chdr(uint8_t *zip, uint32_t coff, uint32_t zsize, unsigned i
465 465
   coff+=CH_clen;
466 466
 
467 467
   if(CH_off<zsize-SIZEOF_LH) {
468
-    lhdr(&zip[CH_off], zsize-CH_off, fu, fc, ch, ret, ctx, tmpd);
468
+    lhdr(&zip[CH_off], zsize-CH_off, fu, fc, ch, ret, ctx, tmpd, fd);
469 469
   } else cli_dbgmsg("cli_unzip: ch - local hdr out of file\n");
470 470
   return last?0:coff;
471 471
 }
... ...
@@ -535,7 +539,7 @@ int cli_unzip(int f, cli_ctx *ctx) {
535 535
 
536 536
   if(coff) {
537 537
     cli_dbgmsg("cli_unzip: central @%x\n", coff);
538
-    while(ret==CL_CLEAN && (coff=chdr(map, coff, fsize, &fu, fc+1, &ret, ctx, tmpd))) {
538
+    while(ret==CL_CLEAN && (coff=chdr(map, coff, fsize, &fu, fc+1, &ret, ctx, tmpd, f))) {
539 539
       fc++;
540 540
       if (ctx->engine->maxfiles && fu>=ctx->engine->maxfiles) {
541 541
 	cli_dbgmsg("cli_unzip: Files limit reached (max: %u)\n", ctx->engine->maxfiles);
... ...
@@ -545,7 +549,7 @@ int cli_unzip(int f, cli_ctx *ctx) {
545 545
   } else cli_dbgmsg("cli_unzip: central not found, using localhdrs\n");
546 546
   if(fu<=(fc/4)) { /* FIXME: make up a sane ratio or remove the whole logic */
547 547
     fc = 0;
548
-    while (ret==CL_CLEAN && lhoff<fsize && (coff=lhdr(&map[lhoff], fsize-lhoff, &fu, fc+1, NULL, &ret, ctx, tmpd))) {
548
+    while (ret==CL_CLEAN && lhoff<fsize && (coff=lhdr(&map[lhoff], fsize-lhoff, &fu, fc+1, NULL, &ret, ctx, tmpd, f))) {
549 549
       fc++;
550 550
       lhoff+=coff;
551 551
       if (ctx->engine->maxfiles && fu>=ctx->engine->maxfiles) {
... ...
@@ -602,7 +606,7 @@ int cli_unzip_single(int f, cli_ctx *ctx, off_t lhoffl) {
602 602
     return CL_EREAD;
603 603
   }
604 604
 #endif
605
-  lhdr(&map[lhoffl], fsize, &fu, 0, NULL, &ret, ctx, NULL);
605
+  lhdr(&map[lhoffl], fsize, &fu, 0, NULL, &ret, ctx, NULL, f);
606 606
 
607 607
   destroy_map(map, st.st_size);
608 608
   return ret;