... | ... |
@@ -853,6 +853,16 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi |
853 | 853 |
val = cl_engine_get_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, NULL); |
854 | 854 |
logg("Limits: MaxZipTypeRcg limit set to %llu bytes.\n", val); |
855 | 855 |
|
856 |
+ if((opt = optget(opts, "MaxPartitions"))->active) { |
|
857 |
+ if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_PARTITIONS, opt->numarg))) { |
|
858 |
+ logg("!cli_engine_set_num(MaxPartitions) failed: %s\n", cl_strerror(ret)); |
|
859 |
+ cl_engine_free(engine); |
|
860 |
+ return 1; |
|
861 |
+ } |
|
862 |
+ } |
|
863 |
+ val = cl_engine_get_num(engine, CL_ENGINE_MAX_PARTITIONS, NULL); |
|
864 |
+ logg("Limits: MaxPartitions limit set to %llu.\n", val); |
|
865 |
+ |
|
856 | 866 |
if(optget(opts, "ScanArchive")->enabled) { |
857 | 867 |
logg("Archive support enabled.\n"); |
858 | 868 |
options |= CL_SCAN_ARCHIVE; |
... | ... |
@@ -952,6 +962,11 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi |
952 | 952 |
} |
953 | 953 |
} |
954 | 954 |
|
955 |
+ if(optget(opts,"PartitionIntersection")->enabled) { |
|
956 |
+ options |= CL_SCAN_PARTITION_INTXN; |
|
957 |
+ logg("Raw DMG: Always checking for partitons intersections\n"); |
|
958 |
+ } |
|
959 |
+ |
|
955 | 960 |
if(optget(opts,"HeuristicScanPrecedence")->enabled) { |
956 | 961 |
options |= CL_SCAN_HEURISTIC_PRECEDENCE; |
957 | 962 |
logg("Heuristic: precedence enabled\n"); |
... | ... |
@@ -823,6 +823,14 @@ int scanmanager(const struct optstruct *opts) |
823 | 823 |
} |
824 | 824 |
} |
825 | 825 |
|
826 |
+ if((opt = optget(opts, "max-partitions"))->active) { |
|
827 |
+ if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_PARTITIONS, opt->numarg))) { |
|
828 |
+ logg("!cli_engine_set_num(CL_ENGINE_MAX_PARTITIONS) failed: %s\n", cl_strerror(ret)); |
|
829 |
+ cl_engine_free(engine); |
|
830 |
+ return 2; |
|
831 |
+ } |
|
832 |
+ } |
|
833 |
+ |
|
826 | 834 |
/* set scan options */ |
827 | 835 |
if(optget(opts, "allmatch")->enabled) |
828 | 836 |
options |= CL_SCAN_ALLMATCHES; |
... | ... |
@@ -833,6 +841,9 @@ int scanmanager(const struct optstruct *opts) |
833 | 833 |
if(optget(opts,"phishing-cloak")->enabled) |
834 | 834 |
options |= CL_SCAN_PHISHING_BLOCKCLOAK; |
835 | 835 |
|
836 |
+ if(optget(opts,"partition-intersection")->enabled) |
|
837 |
+ options |= CL_SCAN_PARTITION_INTXN; |
|
838 |
+ |
|
836 | 839 |
if(optget(opts,"heuristic-scan-precedence")->enabled) |
837 | 840 |
options |= CL_SCAN_HEURISTIC_PRECEDENCE; |
838 | 841 |
|
... | ... |
@@ -150,6 +150,7 @@ typedef enum { |
150 | 150 |
#define CL_SCAN_BLOCKMACROS 0x100000 |
151 | 151 |
#define CL_SCAN_ALLMATCHES 0x200000 |
152 | 152 |
#define CL_SCAN_SWF 0x400000 |
153 |
+#define CL_SCAN_PARTITION_INTXN 0x800000 |
|
153 | 154 |
|
154 | 155 |
#define CL_SCAN_PERFORMANCE_INFO 0x40000000 /* collect performance timings */ |
155 | 156 |
#define CL_SCAN_INTERNAL_COLLECT_SHA 0x80000000 /* Enables hash output in sha-collect builds - for internal use only */ |
... | ... |
@@ -204,7 +205,8 @@ enum cl_engine_field { |
204 | 204 |
CL_ENGINE_MAX_ZIPTYPERCG, /* uint64_t */ |
205 | 205 |
CL_ENGINE_FORCETODISK, /* uint32_t */ |
206 | 206 |
CL_ENGINE_DISABLE_CACHE, /* uint32_t */ |
207 |
- CL_ENGINE_DISABLE_PE_STATS /* uint32_t */ |
|
207 |
+ CL_ENGINE_DISABLE_PE_STATS, /* uint32_t */ |
|
208 |
+ CL_ENGINE_MAX_PARTITIONS /* uint32_t */ |
|
208 | 209 |
}; |
209 | 210 |
|
210 | 211 |
enum bytecode_security { |
... | ... |
@@ -410,6 +410,9 @@ struct cl_engine *cl_engine_new(void) |
410 | 410 |
new->cb_stats_get_size = clamav_stats_get_size; |
411 | 411 |
new->cb_stats_get_hostid = clamav_stats_get_hostid; |
412 | 412 |
|
413 |
+ /* Setup raw dmg max settings */ |
|
414 |
+ new->maxpartitions = 50; |
|
415 |
+ |
|
413 | 416 |
cli_dbgmsg("Initialized %s engine\n", cl_retver()); |
414 | 417 |
return new; |
415 | 418 |
} |
... | ... |
@@ -542,6 +545,9 @@ int cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field field, long |
542 | 542 |
engine->engine_options &= ~(ENGINE_OPTIONS_DISABLE_PE_STATS); |
543 | 543 |
} |
544 | 544 |
break; |
545 |
+ case CL_ENGINE_MAX_PARTITIONS: |
|
546 |
+ engine->maxpartitions = (uint32_t)num; |
|
547 |
+ break; |
|
545 | 548 |
default: |
546 | 549 |
cli_errmsg("cl_engine_set_num: Incorrect field number\n"); |
547 | 550 |
return CL_EARG; |
... | ... |
@@ -609,6 +615,8 @@ long long cl_engine_get_num(const struct cl_engine *engine, enum cl_engine_field |
609 | 609 |
return engine->bytecode_mode; |
610 | 610 |
case CL_ENGINE_DISABLE_CACHE: |
611 | 611 |
return engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE; |
612 |
+ case CL_ENGINE_MAX_PARTITIONS: |
|
613 |
+ return engine->maxpartitions; |
|
612 | 614 |
default: |
613 | 615 |
cli_errmsg("cl_engine_get: Incorrect field number\n"); |
614 | 616 |
if(err) |
... | ... |
@@ -715,6 +723,8 @@ struct cl_settings *cl_engine_settings_copy(const struct cl_engine *engine) |
715 | 715 |
settings->cb_stats_get_size = engine->cb_stats_get_size; |
716 | 716 |
settings->cb_stats_get_hostid = engine->cb_stats_get_hostid; |
717 | 717 |
|
718 |
+ settings->maxpartitions = engine->maxpartitions; |
|
719 |
+ |
|
718 | 720 |
return settings; |
719 | 721 |
} |
720 | 722 |
|
... | ... |
@@ -785,6 +795,8 @@ int cl_engine_settings_apply(struct cl_engine *engine, const struct cl_settings |
785 | 785 |
engine->cb_stats_get_size = settings->cb_stats_get_size; |
786 | 786 |
engine->cb_stats_get_hostid = settings->cb_stats_get_hostid; |
787 | 787 |
|
788 |
+ engine->maxpartitions = settings->maxpartitions; |
|
789 |
+ |
|
788 | 790 |
return CL_SUCCESS; |
789 | 791 |
} |
790 | 792 |
|
... | ... |
@@ -327,6 +327,9 @@ struct cl_engine { |
327 | 327 |
clcb_stats_get_num cb_stats_get_num; |
328 | 328 |
clcb_stats_get_size cb_stats_get_size; |
329 | 329 |
clcb_stats_get_hostid cb_stats_get_hostid; |
330 |
+ |
|
331 |
+ /* Raw dmg max settings */ |
|
332 |
+ uint32_t maxpartitions; |
|
330 | 333 |
}; |
331 | 334 |
|
332 | 335 |
struct cl_settings { |
... | ... |
@@ -378,6 +381,9 @@ struct cl_settings { |
378 | 378 |
clcb_stats_get_num cb_stats_get_num; |
379 | 379 |
clcb_stats_get_size cb_stats_get_size; |
380 | 380 |
clcb_stats_get_hostid cb_stats_get_hostid; |
381 |
+ |
|
382 |
+ /* Raw dmg max settings */ |
|
383 |
+ uint32_t maxpartitions; |
|
381 | 384 |
}; |
382 | 385 |
|
383 | 386 |
extern int (*cli_unrar_open)(int fd, const char *dirname, unrar_state_t *state); |
384 | 387 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,103 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2014 Sourcefire, Inc. |
|
2 |
+ * |
|
3 |
+ * Authors: Kevin Lin <klin@sourcefire.com> |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+#if HAVE_CONFIG_H |
|
21 |
+#include "clamav-config.h" |
|
22 |
+#endif |
|
23 |
+ |
|
24 |
+#include "cltypes.h" |
|
25 |
+#include "others.h" |
|
26 |
+#include "prtn_intxn.h" |
|
27 |
+ |
|
28 |
+static int prtn_intxn_list_is_empty(prtn_intxn_list_t* list) |
|
29 |
+{ |
|
30 |
+ return (list->Head == NULL); |
|
31 |
+} |
|
32 |
+ |
|
33 |
+int prtn_intxn_list_init(prtn_intxn_list_t* list) |
|
34 |
+{ |
|
35 |
+ list->Head = NULL; |
|
36 |
+ list->Size = 0; |
|
37 |
+ return CL_SUCCESS; |
|
38 |
+} |
|
39 |
+ |
|
40 |
+int prtn_intxn_list_check(prtn_intxn_list_t* list, unsigned *pitxn, off_t start, size_t size) |
|
41 |
+{ |
|
42 |
+ prtn_intxn_node_t *new_node, *check_node; |
|
43 |
+ int ret = CL_CLEAN; |
|
44 |
+ |
|
45 |
+ *pitxn = list->Size; |
|
46 |
+ |
|
47 |
+ check_node = list->Head; |
|
48 |
+ while (check_node != NULL) { |
|
49 |
+ (*pitxn)--; |
|
50 |
+ |
|
51 |
+ if (start > check_node->Start) { |
|
52 |
+ if (check_node->Start+check_node->Size > start) { |
|
53 |
+ ret = CL_VIRUS; |
|
54 |
+ break; |
|
55 |
+ } |
|
56 |
+ } |
|
57 |
+ else if (start < check_node->Start) { |
|
58 |
+ if (start+size > check_node->Start) { |
|
59 |
+ ret = CL_VIRUS; |
|
60 |
+ break; |
|
61 |
+ } |
|
62 |
+ } |
|
63 |
+ else { |
|
64 |
+ ret = CL_VIRUS; |
|
65 |
+ break; |
|
66 |
+ } |
|
67 |
+ |
|
68 |
+ check_node = check_node->Next; |
|
69 |
+ } |
|
70 |
+ |
|
71 |
+ /* allocate new node for partition bounds */ |
|
72 |
+ new_node = (prtn_intxn_node_t *) cli_malloc(sizeof(prtn_intxn_node_t)); |
|
73 |
+ if (!new_node) { |
|
74 |
+ cli_dbgmsg("PRTN_INTXN: could not allocate new node for checklist!\n"); |
|
75 |
+ prtn_intxn_list_free(list); |
|
76 |
+ return CL_EMEM; |
|
77 |
+ } |
|
78 |
+ |
|
79 |
+ new_node->Start = start; |
|
80 |
+ new_node->Size = size; |
|
81 |
+ new_node->Next = list->Head; |
|
82 |
+ |
|
83 |
+ list->Head = new_node; |
|
84 |
+ (list->Size)++; |
|
85 |
+ return ret; |
|
86 |
+} |
|
87 |
+ |
|
88 |
+int prtn_intxn_list_free(prtn_intxn_list_t* list) |
|
89 |
+{ |
|
90 |
+ prtn_intxn_node_t *next = NULL; |
|
91 |
+ |
|
92 |
+ while (!prtn_intxn_list_is_empty(list)) { |
|
93 |
+ next = list->Head->Next; |
|
94 |
+ |
|
95 |
+ free(list->Head); |
|
96 |
+ |
|
97 |
+ list->Head = next; |
|
98 |
+ list->Size--; |
|
99 |
+ } |
|
100 |
+ |
|
101 |
+ return CL_SUCCESS; |
|
102 |
+} |
0 | 103 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,47 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2014 Sourcefire, Inc. |
|
2 |
+ * |
|
3 |
+ * Authors: Kevin Lin <klin@sourcefire.com> |
|
4 |
+ * |
|
5 |
+ * This program is free software; you can redistribute it and/or modify |
|
6 |
+ * it under the terms of the GNU General Public License version 2 as |
|
7 |
+ * published by the Free Software Foundation. |
|
8 |
+ * |
|
9 |
+ * This program is distributed in the hope that it will be useful, |
|
10 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
+ * GNU General Public License for more details. |
|
13 |
+ * |
|
14 |
+ * You should have received a copy of the GNU General Public License |
|
15 |
+ * along with this program; if not, write to the Free Software |
|
16 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
17 |
+ * MA 02110-1301, USA. |
|
18 |
+ */ |
|
19 |
+ |
|
20 |
+#ifndef __PRTN_INTXN_H |
|
21 |
+#define __PRTN_INTXN_H |
|
22 |
+ |
|
23 |
+#if HAVE_CONFIG_H |
|
24 |
+#include "clamav-config.h" |
|
25 |
+#endif |
|
26 |
+ |
|
27 |
+#include "cltypes.h" |
|
28 |
+#include "others.h" |
|
29 |
+ |
|
30 |
+struct prtn_intxn_node; |
|
31 |
+typedef struct prtn_intxn_node { |
|
32 |
+ off_t Start; |
|
33 |
+ size_t Size; |
|
34 |
+ struct prtn_intxn_node *Next; |
|
35 |
+} prtn_intxn_node_t; |
|
36 |
+ |
|
37 |
+typedef struct prtn_intxn_list { |
|
38 |
+ struct prtn_intxn_node *Head; |
|
39 |
+ size_t Size; /* for debug */ |
|
40 |
+} prtn_intxn_list_t; |
|
41 |
+ |
|
42 |
+int prtn_intxn_list_init(prtn_intxn_list_t *list); |
|
43 |
+int prtn_intxn_list_check(prtn_intxn_list_t *list, unsigned *pitxn, off_t start, size_t size); |
|
44 |
+int prtn_intxn_list_free(prtn_intxn_list_t *list); |
|
45 |
+ |
|
46 |
+#endif |
... | ... |
@@ -319,6 +319,8 @@ const struct clam_option __clam_options[] = { |
319 | 319 |
|
320 | 320 |
{ "PhishingAlwaysBlockSSLMismatch", "phishing-ssl", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Always block SSL mismatches in URLs, even if they're not in the database.\nThis feature can lead to false positives.", "" }, |
321 | 321 |
|
322 |
+ { "PartitionIntersection", "partition-intersection", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Detect partition intersections in raw dmgs using heuristics.", "yes" }, |
|
323 |
+ |
|
322 | 324 |
{ "HeuristicScanPrecedence", "heuristic-scan-precedence", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Allow heuristic match to take precedence.\nWhen enabled, if a heuristic scan (such as phishingScan) detects\na possible virus/phish it will stop scan immediately. Recommended, saves CPU\nscan-time.\nWhen disabled, virus/phish detected by heuristic scans will be reported only\nat the end of a scan. If an archive contains both a heuristically detected\nvirus/phish, and a real malware, the real malware will be reported.\nKeep this disabled if you intend to handle \"*.Heuristics.*\" viruses\ndifferently from \"real\" malware.\nIf a non-heuristically-detected virus (signature-based) is found first,\nthe scan is interrupted immediately, regardless of this config option.", "yes" }, |
323 | 325 |
|
324 | 326 |
{ "StructuredDataDetection", "detect-structured", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Enable the Data Loss Prevention module.", "no" }, |
... | ... |
@@ -366,6 +368,8 @@ const struct clam_option __clam_options[] = { |
366 | 366 |
|
367 | 367 |
{ "MaxZipTypeRcg", "max-ziptypercg", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXZIPTYPERCG, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum size of a ZIP file to reanalyze type recognition.\nZIP files larger than this value will skip the step to potentially reanalyze as PE.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "1M" }, |
368 | 368 |
|
369 |
+ { "MaxPartitions", "max-partitions", 0, TYPE_NUMBER, MATCH_NUMBER, 50, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum number of partitions of a raw DMG to be scanned.\nRaw DMGs with more partitions than this value will have up to the value number partitions scanned.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "128" }, |
|
370 |
+ |
|
369 | 371 |
/* OnAccess settings */ |
370 | 372 |
{ "ScanOnAccess", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD, "This option enables on-access scanning (Linux only)", "no" }, |
371 | 373 |
|