... | ... |
@@ -166,7 +166,7 @@ static inline int matcher_run(const struct cli_matcher *root, |
166 | 166 |
PERF_LOG_TRIES(acmode, 0, length); |
167 | 167 |
ret = cli_ac_scanbuff(buffer, length, virname, NULL, acres, root, mdata, offset, ftype, ftoffset, acmode, ctx); |
168 | 168 |
if (ret != CL_CLEAN) { |
169 |
- if (ret == CL_VIRUS) { |
|
169 |
+ if (ret == CL_VIRUS) { |
|
170 | 170 |
if (SCAN_ALL) |
171 | 171 |
viruses_found = 1; |
172 | 172 |
else { |
... | ... |
@@ -178,7 +178,7 @@ static inline int matcher_run(const struct cli_matcher *root, |
178 | 178 |
saved_ret = ret; |
179 | 179 |
else |
180 | 180 |
return ret; |
181 |
- } |
|
181 |
+ } |
|
182 | 182 |
|
183 | 183 |
/* due to logical triggered, pcres cannot be evaluated until after full subsig matching */ |
184 | 184 |
/* cannot save pcre execution state without possible evasion; must scan entire buffer */ |
... | ... |
@@ -721,7 +721,7 @@ static int intermediates_eval(cli_ctx *ctx, struct cli_ac_lsig *ac_lsig) |
721 | 721 |
for (i = icnt; i > 0; i--) { |
722 | 722 |
if (ac_lsig->tdb.intermediates[i] == CL_TYPE_ANY) |
723 | 723 |
continue; |
724 |
- if (ac_lsig->tdb.intermediates[i] != cli_get_container_type(ctx, j--)) |
|
724 |
+ if (ac_lsig->tdb.intermediates[i] != cli_get_container_intermediate(ctx, j--)) |
|
725 | 725 |
return 0; |
726 | 726 |
} |
727 | 727 |
return 1; |
... | ... |
@@ -741,7 +741,7 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data |
741 | 741 |
if (rc != CL_SUCCESS) |
742 | 742 |
return rc; |
743 | 743 |
if (cli_ac_chklsig(exp, exp_end, acdata->lsigcnt[lsid], &evalcnt, &evalids, 0) == 1) { |
744 |
- if(ac_lsig->tdb.container && ac_lsig->tdb.container[0] != cli_get_container_type(ctx, -1)) |
|
744 |
+ if(ac_lsig->tdb.container && ac_lsig->tdb.container[0] != cli_get_container(ctx, -1)) |
|
745 | 745 |
return CL_CLEAN; |
746 | 746 |
if(ac_lsig->tdb.intermediates && !intermediates_eval(ctx, ac_lsig)) |
747 | 747 |
return CL_CLEAN; |
... | ... |
@@ -1239,11 +1239,11 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, |
1239 | 1239 |
int ret = CL_CLEAN; |
1240 | 1240 |
|
1241 | 1241 |
cli_dbgmsg("CDBNAME:%s:%llu:%s:%llu:%llu:%d:%u:%u:%p\n", |
1242 |
- cli_ftname(cli_get_container_type(ctx, -1)), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer, |
|
1242 |
+ cli_ftname(cli_get_container(ctx, -1)), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer, |
|
1243 | 1243 |
encrypted, filepos, res1, res2); |
1244 | 1244 |
|
1245 | 1245 |
if (ctx->engine && ctx->engine->cb_meta) |
1246 |
- if (ctx->engine->cb_meta(cli_ftname(cli_get_container_type(ctx, -1)), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) { |
|
1246 |
+ if (ctx->engine->cb_meta(cli_ftname(cli_get_container(ctx, -1)), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) { |
|
1247 | 1247 |
cli_dbgmsg("inner file blacklisted by callback: %s\n", fname); |
1248 | 1248 |
|
1249 | 1249 |
ret = cli_append_virus(ctx, "Detected.By.Callback"); |
... | ... |
@@ -1256,7 +1256,7 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, |
1256 | 1256 |
return CL_CLEAN; |
1257 | 1257 |
|
1258 | 1258 |
do { |
1259 |
- if(cdb->ctype != CL_TYPE_ANY && cdb->ctype != cli_get_container_type(ctx, -1)) |
|
1259 |
+ if(cdb->ctype != CL_TYPE_ANY && cdb->ctype != cli_get_container(ctx, -1)) |
|
1260 | 1260 |
continue; |
1261 | 1261 |
|
1262 | 1262 |
if(cdb->encrypted != 2 && cdb->encrypted != encrypted) |
... | ... |
@@ -1163,12 +1163,28 @@ void cli_set_container(cli_ctx *ctx, cli_file_t type, size_t size) |
1163 | 1163 |
{ |
1164 | 1164 |
ctx->containers[ctx->recursion].type = type; |
1165 | 1165 |
ctx->containers[ctx->recursion].size = size; |
1166 |
+ if (type >= CL_TYPE_MSEXE && type != CL_TYPE_OTHER && type != CL_TYPE_IGNORED) |
|
1167 |
+ ctx->containers[ctx->recursion].flag = CONTAINER_FLAG_VALID; |
|
1168 |
+ else |
|
1169 |
+ ctx->containers[ctx->recursion].flag = 0; |
|
1166 | 1170 |
} |
1167 | 1171 |
|
1168 |
-cli_file_t cli_get_container_type(cli_ctx *ctx, int index) |
|
1172 |
+cli_file_t cli_get_container(cli_ctx *ctx, int index) |
|
1169 | 1173 |
{ |
1170 | 1174 |
if (index < 0) |
1171 | 1175 |
index = ctx->recursion + index + 1; |
1176 |
+ while (index >= 0 && index <= ctx->recursion) { |
|
1177 |
+ if (ctx->containers[index].flag & CONTAINER_FLAG_VALID) |
|
1178 |
+ return ctx->containers[index].type; |
|
1179 |
+ index--; |
|
1180 |
+ } |
|
1181 |
+ return CL_TYPE_ANY; |
|
1182 |
+} |
|
1183 |
+ |
|
1184 |
+cli_file_t cli_get_container_intermediate(cli_ctx *ctx, int index) |
|
1185 |
+{ |
|
1186 |
+ if (index < 0) |
|
1187 |
+ index = ctx->recursion + index + 1; |
|
1172 | 1188 |
if (index >= 0 && index <= ctx->recursion) |
1173 | 1189 |
return ctx->containers[index].type; |
1174 | 1190 |
return CL_TYPE_ANY; |
... | ... |
@@ -1178,8 +1194,11 @@ size_t cli_get_container_size(cli_ctx *ctx, int index) |
1178 | 1178 |
{ |
1179 | 1179 |
if (index < 0) |
1180 | 1180 |
index = ctx->recursion + index + 1; |
1181 |
- if (index >= 0 && index <= ctx->recursion) |
|
1182 |
- return ctx->containers[index].size; |
|
1181 |
+ while (index >= 0 && index <= ctx->recursion) { |
|
1182 |
+ if (ctx->containers[index].flag & CONTAINER_FLAG_VALID) |
|
1183 |
+ return ctx->containers[index].size; |
|
1184 |
+ index--; |
|
1185 |
+ } |
|
1183 | 1186 |
return 0; |
1184 | 1187 |
} |
1185 | 1188 |
|
... | ... |
@@ -129,7 +129,9 @@ typedef struct bitset_tag |
129 | 129 |
typedef struct cli_ctx_container_tag { |
130 | 130 |
cli_file_t type; |
131 | 131 |
size_t size; |
132 |
+ unsigned char flag; |
|
132 | 133 |
} cli_ctx_container; |
134 |
+#define CONTAINER_FLAG_VALID 0x01 |
|
133 | 135 |
|
134 | 136 |
/* internal clamav context */ |
135 | 137 |
typedef struct cli_ctx_tag { |
... | ... |
@@ -607,8 +609,9 @@ const char *cli_get_last_virus_str(const cli_ctx *ctx); |
607 | 607 |
void cli_virus_found_cb(cli_ctx *ctx); |
608 | 608 |
|
609 | 609 |
void cli_set_container(cli_ctx *ctx, cli_file_t type, size_t size); |
610 |
-cli_file_t cli_get_container_type(cli_ctx *ctx, int index); |
|
610 |
+cli_file_t cli_get_container(cli_ctx *ctx, int index); |
|
611 | 611 |
size_t cli_get_container_size(cli_ctx *ctx, int index); |
612 |
+cli_file_t cli_get_container_intermediate(cli_ctx *ctx, int index); |
|
612 | 613 |
|
613 | 614 |
/* used by: spin, yc (C) aCaB */ |
614 | 615 |
#define __SHIFTBITS(a) (sizeof(a)<<3) |
... | ... |
@@ -2366,7 +2366,7 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2366 | 2366 |
if(nret != CL_VIRUS) switch(ret) { |
2367 | 2367 |
case CL_TYPE_HTML: |
2368 | 2368 |
/* bb#11196 - autoit script file misclassified as HTML */ |
2369 |
- if (cli_get_container_type(ctx, -2) == CL_TYPE_AUTOIT) { |
|
2369 |
+ if (cli_get_container_intermediate(ctx, -2) == CL_TYPE_AUTOIT) { |
|
2370 | 2370 |
ret = CL_TYPE_TEXT_ASCII; |
2371 | 2371 |
} else if (SCAN_HTML && (type == CL_TYPE_TEXT_ASCII || type == CL_TYPE_GRAPHICS) && |
2372 | 2372 |
(DCONF_DOC & DOC_CONF_HTML)) { |
... | ... |
@@ -3146,7 +3146,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
3146 | 3146 |
perf_nested_start(ctx, PERFT_SCRIPT, PERFT_SCAN); |
3147 | 3147 |
if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML && (ret != CL_VIRUS || SCAN_ALL) && SCAN_HTML) |
3148 | 3148 |
ret = cli_scanscript(ctx); |
3149 |
- if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX) && ret != CL_VIRUS && (cli_get_container_type(ctx, -1) == CL_TYPE_MAIL || dettype == CL_TYPE_MAIL)) { |
|
3149 |
+ if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX) && ret != CL_VIRUS && (cli_get_container(ctx, -1) == CL_TYPE_MAIL || dettype == CL_TYPE_MAIL)) { |
|
3150 | 3150 |
ret = cli_fmap_scandesc(ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL, NULL); |
3151 | 3151 |
} |
3152 | 3152 |
perf_nested_stop(ctx, PERFT_SCRIPT, PERFT_SCAN); |