... | ... |
@@ -525,13 +525,13 @@ int32_t cli_bcapi_extract_new(struct cli_bc_ctx *ctx, int32_t id) |
525 | 525 |
cli_dbgmsg("bytecode: scanning extracted file %s\n", ctx->tempfile); |
526 | 526 |
cctx = (cli_ctx*)ctx->ctx; |
527 | 527 |
if (cctx) { |
528 |
- cli_file_t current = cctx->container_type; |
|
529 |
- if (ctx->containertype != CL_TYPE_ANY) |
|
530 |
- cctx->container_type = ctx->containertype; |
|
531 | 528 |
cctx->recursion++; |
529 |
+ if (ctx->containertype != CL_TYPE_ANY) { |
|
530 |
+ size_t csize = cli_get_container_size(cctx, -1); |
|
531 |
+ cli_set_container(cctx, ctx->containertype, csize); |
|
532 |
+ } |
|
532 | 533 |
res = cli_magic_scandesc(ctx->outfd, cctx); |
533 | 534 |
cctx->recursion--; |
534 |
- cctx->container_type = current; |
|
535 | 535 |
if (res == CL_VIRUS) { |
536 | 536 |
ctx->virname = cli_get_last_virus(cctx); |
537 | 537 |
ctx->found = 1; |
... | ... |
@@ -717,7 +717,7 @@ static int lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data |
717 | 717 |
if (rc != CL_SUCCESS) |
718 | 718 |
return rc; |
719 | 719 |
if (cli_ac_chklsig(exp, exp_end, acdata->lsigcnt[lsid], &evalcnt, &evalids, 0) == 1) { |
720 |
- if(ac_lsig->tdb.container && ac_lsig->tdb.container[0] != ctx->container_type) |
|
720 |
+ if(ac_lsig->tdb.container && ac_lsig->tdb.container[0] != cli_get_container_type(ctx, -1)) |
|
721 | 721 |
return CL_CLEAN; |
722 | 722 |
if(ac_lsig->tdb.filesize && (ac_lsig->tdb.filesize[0] > map->len || ac_lsig->tdb.filesize[1] < map->len)) |
723 | 723 |
return CL_CLEAN; |
... | ... |
@@ -1211,11 +1211,11 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, |
1211 | 1211 |
unsigned int viruses_found = 0; |
1212 | 1212 |
|
1213 | 1213 |
cli_dbgmsg("CDBNAME:%s:%llu:%s:%llu:%llu:%d:%u:%u:%p\n", |
1214 |
- cli_ftname(ctx->container_type), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer, |
|
1214 |
+ cli_ftname(cli_get_container_type(ctx, -1)), (long long unsigned)fsizec, fname, (long long unsigned)fsizec, (long long unsigned)fsizer, |
|
1215 | 1215 |
encrypted, filepos, res1, res2); |
1216 | 1216 |
|
1217 | 1217 |
if (ctx->engine && ctx->engine->cb_meta) |
1218 |
- if (ctx->engine->cb_meta(cli_ftname(ctx->container_type), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) { |
|
1218 |
+ if (ctx->engine->cb_meta(cli_ftname(cli_get_container_type(ctx, -1)), fsizec, fname, fsizer, encrypted, filepos, ctx->cb_ctx) == CL_VIRUS) { |
|
1219 | 1219 |
cli_dbgmsg("inner file blacklisted by callback: %s\n", fname); |
1220 | 1220 |
|
1221 | 1221 |
cli_append_virus(ctx, "Detected.By.Callback"); |
... | ... |
@@ -1228,7 +1228,7 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, |
1228 | 1228 |
return CL_CLEAN; |
1229 | 1229 |
|
1230 | 1230 |
do { |
1231 |
- if(cdb->ctype != CL_TYPE_ANY && cdb->ctype != ctx->container_type) |
|
1231 |
+ if(cdb->ctype != CL_TYPE_ANY && cdb->ctype != cli_get_container_type(ctx, -1)) |
|
1232 | 1232 |
continue; |
1233 | 1233 |
|
1234 | 1234 |
if(cdb->encrypted != 2 && cdb->encrypted != encrypted) |
... | ... |
@@ -1246,7 +1246,7 @@ int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, |
1246 | 1246 |
continue; \ |
1247 | 1247 |
} |
1248 | 1248 |
|
1249 |
- CDBRANGE(cdb->csize, ctx->container_size); |
|
1249 |
+ CDBRANGE(cdb->csize, cli_get_container_size(ctx, -1)); |
|
1250 | 1250 |
CDBRANGE(cdb->fsizec, fsizec); |
1251 | 1251 |
CDBRANGE(cdb->fsizer, fsizer); |
1252 | 1252 |
CDBRANGE(cdb->filepos, filepos); |
... | ... |
@@ -1134,6 +1134,30 @@ const char * cli_get_last_virus_str(const cli_ctx * ctx) |
1134 | 1134 |
return ""; |
1135 | 1135 |
} |
1136 | 1136 |
|
1137 |
+void cli_set_container(cli_ctx *ctx, cli_file_t type, size_t size) |
|
1138 |
+{ |
|
1139 |
+ ctx->containers[ctx->recursion].type = type; |
|
1140 |
+ ctx->containers[ctx->recursion].size = size; |
|
1141 |
+} |
|
1142 |
+ |
|
1143 |
+cli_file_t cli_get_container_type(cli_ctx *ctx, int index) |
|
1144 |
+{ |
|
1145 |
+ if (index < 0) |
|
1146 |
+ index = ctx->recursion + index + 1; |
|
1147 |
+ if (index >= 0 || index <= ctx->recursion) |
|
1148 |
+ return ctx->containers[index].type; |
|
1149 |
+ return CL_TYPE_ANY; |
|
1150 |
+} |
|
1151 |
+ |
|
1152 |
+size_t cli_get_container_size(cli_ctx *ctx, int index) |
|
1153 |
+{ |
|
1154 |
+ if (index < 0) |
|
1155 |
+ index = ctx->recursion + index + 1; |
|
1156 |
+ if (index >= 0 || index <= ctx->recursion) |
|
1157 |
+ return ctx->containers[index].size; |
|
1158 |
+ return 0; |
|
1159 |
+} |
|
1160 |
+ |
|
1137 | 1161 |
|
1138 | 1162 |
|
1139 | 1163 |
#ifdef C_WINDOWS |
... | ... |
@@ -126,6 +126,11 @@ typedef struct bitset_tag |
126 | 126 |
unsigned long length; |
127 | 127 |
} bitset_t; |
128 | 128 |
|
129 |
+typedef struct cli_ctx_container_tag { |
|
130 |
+ cli_file_t type; |
|
131 |
+ size_t size; |
|
132 |
+} cli_ctx_container; |
|
133 |
+ |
|
129 | 134 |
/* internal clamav context */ |
130 | 135 |
typedef struct cli_ctx_tag { |
131 | 136 |
const char **virname; |
... | ... |
@@ -140,8 +145,7 @@ typedef struct cli_ctx_tag { |
140 | 140 |
unsigned int found_possibly_unwanted; |
141 | 141 |
unsigned int corrupted_input; |
142 | 142 |
unsigned int img_validate; |
143 |
- cli_file_t container_type; /* FIXME: to be made into a stack or array - see bb#1579 & bb#1293 */ |
|
144 |
- size_t container_size; |
|
143 |
+ cli_ctx_container *containers; /* set container type after recurse */ |
|
145 | 144 |
unsigned char handlertype_hash[16]; |
146 | 145 |
struct cli_dconf *dconf; |
147 | 146 |
fmap_t **fmap; |
... | ... |
@@ -601,6 +605,10 @@ void cli_append_virus(cli_ctx *ctx, const char *virname); |
601 | 601 |
const char *cli_get_last_virus(const cli_ctx *ctx); |
602 | 602 |
const char *cli_get_last_virus_str(const cli_ctx *ctx); |
603 | 603 |
|
604 |
+void cli_set_container(cli_ctx *ctx, cli_file_t type, size_t size); |
|
605 |
+cli_file_t cli_get_container_type(cli_ctx *ctx, int index); |
|
606 |
+size_t cli_get_container_size(cli_ctx *ctx, int index); |
|
607 |
+ |
|
604 | 608 |
/* used by: spin, yc (C) aCaB */ |
605 | 609 |
#define __SHIFTBITS(a) (sizeof(a)<<3) |
606 | 610 |
#define __SHIFTMASK(a) (__SHIFTBITS(a)-1) |
... | ... |
@@ -2134,8 +2134,6 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2134 | 2134 |
struct cli_exe_info peinfo; |
2135 | 2135 |
unsigned int acmode = AC_SCAN_VIR, break_loop = 0; |
2136 | 2136 |
fmap_t *map = *ctx->fmap; |
2137 |
- cli_file_t current_container_type = ctx->container_type; |
|
2138 |
- size_t current_container_size = ctx->container_size; |
|
2139 | 2137 |
|
2140 | 2138 |
|
2141 | 2139 |
if(ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel) { |
... | ... |
@@ -2157,9 +2155,10 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2157 | 2157 |
fpt = ftoffset; |
2158 | 2158 |
|
2159 | 2159 |
while(fpt) { |
2160 |
+ /* set current level as container AFTER recursing */ |
|
2161 |
+ cli_set_container(ctx, fpt->type, map->len); |
|
2160 | 2162 |
if(fpt->offset) switch(fpt->type) { |
2161 | 2163 |
case CL_TYPE_MHTML: |
2162 |
- ctx->container_type = CL_TYPE_MHTML; |
|
2163 | 2164 |
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) { |
2164 | 2165 |
cli_dbgmsg("MHTML signature found at %u\n", (unsigned int) fpt->offset); |
2165 | 2166 |
ret = cli_scanmail(ctx); |
... | ... |
@@ -2194,8 +2193,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2194 | 2194 |
if(type != CL_TYPE_RAR && have_rar && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR)) { |
2195 | 2195 |
char *tmpname = NULL; |
2196 | 2196 |
int tmpfd = fmap_fd(map); |
2197 |
- ctx->container_type = CL_TYPE_RAR; |
|
2198 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2197 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2198 |
+ cli_set_container(ctx, CL_TYPE_RAR, csize); |
|
2199 | 2199 |
cli_dbgmsg("RAR/RAR-SFX signature found at %u\n", (unsigned int) fpt->offset); |
2200 | 2200 |
/* if map is not file-backed, have to dump to file for scanrar */ |
2201 | 2201 |
if(tmpfd == -1) { |
... | ... |
@@ -2225,8 +2224,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2225 | 2225 |
|
2226 | 2226 |
case CL_TYPE_ZIPSFX: |
2227 | 2227 |
if(type != CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) { |
2228 |
- ctx->container_type = CL_TYPE_ZIP; |
|
2229 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2228 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2229 |
+ cli_set_container(ctx, CL_TYPE_ZIP, csize); |
|
2230 | 2230 |
cli_dbgmsg("ZIP/ZIP-SFX signature found at %u\n", (unsigned int) fpt->offset); |
2231 | 2231 |
nret = cli_unzip_single(ctx, fpt->offset); |
2232 | 2232 |
} |
... | ... |
@@ -2234,8 +2233,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2234 | 2234 |
|
2235 | 2235 |
case CL_TYPE_CABSFX: |
2236 | 2236 |
if(type != CL_TYPE_MSCAB && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB)) { |
2237 |
- ctx->container_type = CL_TYPE_MSCAB; |
|
2238 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2237 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2238 |
+ cli_set_container(ctx, CL_TYPE_MSCAB, csize); |
|
2239 | 2239 |
cli_dbgmsg("CAB/CAB-SFX signature found at %u\n", (unsigned int) fpt->offset); |
2240 | 2240 |
nret = cli_scanmscab(ctx, fpt->offset); |
2241 | 2241 |
} |
... | ... |
@@ -2243,8 +2242,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2243 | 2243 |
|
2244 | 2244 |
case CL_TYPE_ARJSFX: |
2245 | 2245 |
if(type != CL_TYPE_ARJ && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ)) { |
2246 |
- ctx->container_type = CL_TYPE_ARJ; |
|
2247 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2246 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2247 |
+ cli_set_container(ctx, CL_TYPE_ARJ, csize); |
|
2248 | 2248 |
cli_dbgmsg("ARJ-SFX signature found at %u\n", (unsigned int) fpt->offset); |
2249 | 2249 |
nret = cli_scanarj(ctx, fpt->offset, &lastrar); |
2250 | 2250 |
} |
... | ... |
@@ -2252,8 +2251,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2252 | 2252 |
|
2253 | 2253 |
case CL_TYPE_7ZSFX: |
2254 | 2254 |
if(type != CL_TYPE_7Z && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z)) { |
2255 |
- ctx->container_type = CL_TYPE_7Z; |
|
2256 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2255 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2256 |
+ cli_set_container(ctx, CL_TYPE_7Z, csize); |
|
2257 | 2257 |
cli_dbgmsg("7Zip-SFX signature found at %u\n", (unsigned int) fpt->offset); |
2258 | 2258 |
nret = cli_7unz(ctx, fpt->offset); |
2259 | 2259 |
} |
... | ... |
@@ -2261,8 +2260,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2261 | 2261 |
|
2262 | 2262 |
case CL_TYPE_ISO9660: |
2263 | 2263 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ISO9660)) { |
2264 |
- ctx->container_type = CL_TYPE_ISO9660; |
|
2265 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2264 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2265 |
+ cli_set_container(ctx, CL_TYPE_ISO9660, csize); |
|
2266 | 2266 |
cli_dbgmsg("ISO9660 signature found at %u\n", (unsigned int) fpt->offset); |
2267 | 2267 |
nret = cli_scaniso(ctx, fpt->offset); |
2268 | 2268 |
} |
... | ... |
@@ -2271,8 +2270,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2271 | 2271 |
case CL_TYPE_NULSFT: |
2272 | 2272 |
if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_NSIS) && |
2273 | 2273 |
fpt->offset > 4) { |
2274 |
- ctx->container_type = CL_TYPE_NULSFT; |
|
2275 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2274 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2275 |
+ cli_set_container(ctx, CL_TYPE_NULSFT, csize); |
|
2276 | 2276 |
cli_dbgmsg("NSIS signature found at %u\n", (unsigned int) fpt->offset-4); |
2277 | 2277 |
nret = cli_scannulsft(ctx, fpt->offset - 4); |
2278 | 2278 |
} |
... | ... |
@@ -2280,8 +2279,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2280 | 2280 |
|
2281 | 2281 |
case CL_TYPE_AUTOIT: |
2282 | 2282 |
if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_AUTOIT)) { |
2283 |
- ctx->container_type = CL_TYPE_AUTOIT; |
|
2284 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2283 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2284 |
+ cli_set_container(ctx, CL_TYPE_AUTOIT, csize); |
|
2285 | 2285 |
cli_dbgmsg("AUTOIT signature found at %u\n", (unsigned int) fpt->offset); |
2286 | 2286 |
nret = cli_scanautoit(ctx, fpt->offset + 23); |
2287 | 2287 |
} |
... | ... |
@@ -2289,8 +2288,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2289 | 2289 |
|
2290 | 2290 |
case CL_TYPE_ISHIELD_MSI: |
2291 | 2291 |
if(SCAN_ARCHIVE && type == CL_TYPE_MSEXE && (DCONF_ARCH & ARCH_CONF_ISHIELD)) { |
2292 |
- ctx->container_type = CL_TYPE_AUTOIT; |
|
2293 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2292 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2293 |
+ cli_set_container(ctx, CL_TYPE_AUTOIT, csize); |
|
2294 | 2294 |
cli_dbgmsg("ISHIELD-MSI signature found at %u\n", (unsigned int) fpt->offset); |
2295 | 2295 |
nret = cli_scanishield_msi(ctx, fpt->offset + 14); |
2296 | 2296 |
} |
... | ... |
@@ -2298,7 +2297,6 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2298 | 2298 |
|
2299 | 2299 |
case CL_TYPE_DMG: |
2300 | 2300 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_DMG)) { |
2301 |
- ctx->container_type = CL_TYPE_DMG; |
|
2302 | 2301 |
cli_dbgmsg("DMG signature found at %u\n", (unsigned int) fpt->offset); |
2303 | 2302 |
nret = cli_scandmg(ctx); |
2304 | 2303 |
} |
... | ... |
@@ -2309,12 +2307,11 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2309 | 2309 |
int iret = cli_mbr_check2(ctx, 0); |
2310 | 2310 |
if ((iret == CL_TYPE_GPT) && (DCONF_ARCH & ARCH_CONF_GPT)) { |
2311 | 2311 |
cli_dbgmsg("Recognized GUID Partition Table file\n"); |
2312 |
- ctx->container_type = CL_TYPE_GPT; |
|
2312 |
+ cli_set_container(ctx, CL_TYPE_GPT, map->len); |
|
2313 | 2313 |
cli_dbgmsg("GPT signature found at %u\n", (unsigned int) fpt->offset); |
2314 | 2314 |
nret = cli_scangpt(ctx, 0); |
2315 | 2315 |
} |
2316 | 2316 |
else if ((iret == CL_CLEAN) && (DCONF_ARCH & ARCH_CONF_MBR)) { |
2317 |
- ctx->container_type = CL_TYPE_MBR; |
|
2318 | 2317 |
cli_dbgmsg("MBR signature found at %u\n", (unsigned int) fpt->offset); |
2319 | 2318 |
nret = cli_scanmbr(ctx, 0); |
2320 | 2319 |
} |
... | ... |
@@ -2323,8 +2320,8 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2323 | 2323 |
|
2324 | 2324 |
case CL_TYPE_PDF: |
2325 | 2325 |
if(type != CL_TYPE_PDF && SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) { |
2326 |
- ctx->container_type = CL_TYPE_PDF; |
|
2327 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2326 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2327 |
+ cli_set_container(ctx, CL_TYPE_PDF, csize); |
|
2328 | 2328 |
cli_dbgmsg("PDF signature found at %u\n", (unsigned int) fpt->offset); |
2329 | 2329 |
nret = cli_scanpdf(ctx, fpt->offset); |
2330 | 2330 |
} |
... | ... |
@@ -2334,13 +2331,13 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2334 | 2334 |
if(SCAN_PE && (type == CL_TYPE_MSEXE || type == CL_TYPE_ZIP || type == CL_TYPE_MSOLE2) |
2335 | 2335 |
&& ctx->dconf->pe) { |
2336 | 2336 |
uint64_t curr_len = map->len; |
2337 |
+ size_t csize = map->len - fpt->offset; /* not precise */ |
|
2337 | 2338 |
/* CL_ENGINE_MAX_EMBEDDED_PE */ |
2338 | 2339 |
if(curr_len > ctx->engine->maxembeddedpe) { |
2339 | 2340 |
cli_dbgmsg("cli_scanraw: MaxEmbeddedPE exceeded\n"); |
2340 | 2341 |
break; |
2341 | 2342 |
} |
2342 |
- ctx->container_type = CL_TYPE_MSEXE; /* PE is a container for another executable here */ |
|
2343 |
- ctx->container_size = map->len - fpt->offset; /* not precise */ |
|
2343 |
+ cli_set_container(ctx, CL_TYPE_MSEXE, csize); |
|
2344 | 2344 |
memset(&peinfo, 0, sizeof(struct cli_exe_info)); |
2345 | 2345 |
peinfo.offset = fpt->offset; |
2346 | 2346 |
if(cli_peheader(map, &peinfo) == 0) { |
... | ... |
@@ -2369,13 +2366,11 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2369 | 2369 |
|
2370 | 2370 |
fpt = fpt->next; |
2371 | 2371 |
} |
2372 |
- ctx->container_type = current_container_type; |
|
2373 |
- ctx->container_size = current_container_size; |
|
2374 | 2372 |
|
2375 | 2373 |
if(nret != CL_VIRUS) switch(ret) { |
2376 | 2374 |
case CL_TYPE_HTML: |
2377 | 2375 |
/* bb#11196 - autoit script file misclassified as HTML */ |
2378 |
- if (ctx->container_type == CL_TYPE_AUTOIT) { |
|
2376 |
+ if (cli_get_container_type(ctx, -1) == CL_TYPE_AUTOIT) { |
|
2379 | 2377 |
ret = CL_TYPE_TEXT_ASCII; |
2380 | 2378 |
} else if (SCAN_HTML && (type == CL_TYPE_TEXT_ASCII || type == CL_TYPE_GRAPHICS) && |
2381 | 2379 |
(DCONF_DOC & DOC_CONF_HTML)) { |
... | ... |
@@ -2385,14 +2380,11 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_ |
2385 | 2385 |
break; |
2386 | 2386 |
|
2387 | 2387 |
case CL_TYPE_MAIL: |
2388 |
- ctx->container_type = CL_TYPE_MAIL; |
|
2389 |
- ctx->container_size = map->len; |
|
2388 |
+ cli_set_container(ctx, CL_TYPE_MAIL, map->len); |
|
2390 | 2389 |
if(SCAN_MAIL && type == CL_TYPE_TEXT_ASCII && (DCONF_MAIL & MAIL_CONF_MBOX)) { |
2391 | 2390 |
*dettype = CL_TYPE_MAIL; |
2392 | 2391 |
nret = cli_scanmail(ctx); |
2393 | 2392 |
} |
2394 |
- ctx->container_type = current_container_type; |
|
2395 |
- ctx->container_size = current_container_size; |
|
2396 | 2393 |
break; |
2397 | 2394 |
|
2398 | 2395 |
default: |
... | ... |
@@ -2535,17 +2527,16 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2535 | 2535 |
int ret = CL_CLEAN; |
2536 | 2536 |
cli_file_t dettype = 0; |
2537 | 2537 |
uint8_t typercg = 1; |
2538 |
- cli_file_t current_container_type = ctx->container_type; |
|
2539 |
- size_t current_container_size = ctx->container_size, hashed_size; |
|
2538 |
+ size_t hashed_size; |
|
2540 | 2539 |
unsigned char hash[16] = {'\0'}; |
2541 | 2540 |
bitset_t *old_hook_lsig_matches; |
2542 | 2541 |
const char *filetype; |
2543 | 2542 |
int cache_clean = 0, res; |
2544 |
- int run_cleanup = 0; |
|
2543 |
+ int run_cleanup = 0; |
|
2545 | 2544 |
#if HAVE_JSON |
2546 | 2545 |
struct json_object *parent_property = NULL; |
2547 | 2546 |
#else |
2548 |
- void *parent_property = NULL; |
|
2547 |
+ void *parent_property = NULL; |
|
2549 | 2548 |
#endif |
2550 | 2549 |
|
2551 | 2550 |
if(!ctx->engine) { |
... | ... |
@@ -2759,7 +2750,8 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2759 | 2759 |
|
2760 | 2760 |
ctx->recursion++; |
2761 | 2761 |
perf_nested_start(ctx, PERFT_CONTAINER, PERFT_SCAN); |
2762 |
- ctx->container_size = (*ctx->fmap)->len; |
|
2762 |
+ /* set current level as container AFTER recursing */ |
|
2763 |
+ cli_set_container(ctx, type, (*ctx->fmap)->len); |
|
2763 | 2764 |
switch(type) { |
2764 | 2765 |
case CL_TYPE_IGNORED: |
2765 | 2766 |
break; |
... | ... |
@@ -2795,7 +2787,6 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2795 | 2795 |
break; |
2796 | 2796 |
|
2797 | 2797 |
case CL_TYPE_RAR: |
2798 |
- ctx->container_type = CL_TYPE_RAR; |
|
2799 | 2798 |
if(have_rar && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR)) { |
2800 | 2799 |
char *tmpname = NULL; |
2801 | 2800 |
int desc = fmap_fd(*ctx->fmap); |
... | ... |
@@ -2841,7 +2832,6 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2841 | 2841 |
} |
2842 | 2842 |
#endif |
2843 | 2843 |
case CL_TYPE_ZIP: |
2844 |
- ctx->container_type = CL_TYPE_ZIP; |
|
2845 | 2844 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) |
2846 | 2845 |
ret = cli_unzip(ctx); |
2847 | 2846 |
break; |
... | ... |
@@ -2872,19 +2862,16 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2872 | 2872 |
break; |
2873 | 2873 |
|
2874 | 2874 |
case CL_TYPE_ARJ: |
2875 |
- ctx->container_type = CL_TYPE_ARJ; |
|
2876 | 2875 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ)) |
2877 | 2876 |
ret = cli_scanarj(ctx, 0, NULL); |
2878 | 2877 |
break; |
2879 | 2878 |
|
2880 | 2879 |
case CL_TYPE_NULSFT: |
2881 |
- ctx->container_type = CL_TYPE_NULSFT; |
|
2882 | 2880 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS)) |
2883 | 2881 |
ret = cli_scannulsft(ctx, 0); |
2884 | 2882 |
break; |
2885 | 2883 |
|
2886 | 2884 |
case CL_TYPE_AUTOIT: |
2887 |
- ctx->container_type = CL_TYPE_AUTOIT; |
|
2888 | 2885 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_AUTOIT)) |
2889 | 2886 |
ret = cli_scanautoit(ctx, 23); |
2890 | 2887 |
break; |
... | ... |
@@ -2895,7 +2882,6 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2895 | 2895 |
break; |
2896 | 2896 |
|
2897 | 2897 |
case CL_TYPE_MSCAB: |
2898 |
- ctx->container_type = CL_TYPE_MSCAB; |
|
2899 | 2898 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB)) |
2900 | 2899 |
ret = cli_scanmscab(ctx, 0); |
2901 | 2900 |
break; |
... | ... |
@@ -2921,19 +2907,16 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2921 | 2921 |
break; |
2922 | 2922 |
|
2923 | 2923 |
case CL_TYPE_RTF: |
2924 |
- ctx->container_type = CL_TYPE_RTF; |
|
2925 | 2924 |
if(SCAN_ARCHIVE && (DCONF_DOC & DOC_CONF_RTF)) |
2926 | 2925 |
ret = cli_scanrtf(ctx); |
2927 | 2926 |
break; |
2928 | 2927 |
|
2929 | 2928 |
case CL_TYPE_MAIL: |
2930 |
- ctx->container_type = CL_TYPE_MAIL; |
|
2931 | 2929 |
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) |
2932 | 2930 |
ret = cli_scanmail(ctx); |
2933 | 2931 |
break; |
2934 | 2932 |
|
2935 | 2933 |
case CL_TYPE_MHTML: |
2936 |
- ctx->container_type = CL_TYPE_MHTML; |
|
2937 | 2934 |
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX)) |
2938 | 2935 |
ret = cli_scanmail(ctx); |
2939 | 2936 |
break; |
... | ... |
@@ -2949,55 +2932,46 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
2949 | 2949 |
break; |
2950 | 2950 |
|
2951 | 2951 |
case CL_TYPE_MSCHM: |
2952 |
- ctx->container_type = CL_TYPE_MSCHM; |
|
2953 | 2952 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CHM)) |
2954 | 2953 |
ret = cli_scanmschm(ctx); |
2955 | 2954 |
break; |
2956 | 2955 |
|
2957 | 2956 |
case CL_TYPE_MSOLE2: |
2958 |
- ctx->container_type = CL_TYPE_MSOLE2; |
|
2959 | 2957 |
if(SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2)) |
2960 | 2958 |
ret = cli_scanole2(ctx); |
2961 | 2959 |
break; |
2962 | 2960 |
|
2963 | 2961 |
case CL_TYPE_7Z: |
2964 |
- ctx->container_type = CL_TYPE_7Z; |
|
2965 | 2962 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z)) |
2966 | 2963 |
ret = cli_7unz(ctx, 0); |
2967 | 2964 |
break; |
2968 | 2965 |
|
2969 | 2966 |
case CL_TYPE_POSIX_TAR: |
2970 |
- ctx->container_type = CL_TYPE_POSIX_TAR; |
|
2971 | 2967 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR)) |
2972 | 2968 |
ret = cli_scantar(ctx, 1); |
2973 | 2969 |
break; |
2974 | 2970 |
|
2975 | 2971 |
case CL_TYPE_OLD_TAR: |
2976 |
- ctx->container_type = CL_TYPE_OLD_TAR; |
|
2977 | 2972 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR)) |
2978 | 2973 |
ret = cli_scantar(ctx, 0); |
2979 | 2974 |
break; |
2980 | 2975 |
|
2981 | 2976 |
case CL_TYPE_CPIO_OLD: |
2982 |
- ctx->container_type = CL_TYPE_CPIO_OLD; |
|
2983 | 2977 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
2984 | 2978 |
ret = cli_scancpio_old(ctx); |
2985 | 2979 |
break; |
2986 | 2980 |
|
2987 | 2981 |
case CL_TYPE_CPIO_ODC: |
2988 |
- ctx->container_type = CL_TYPE_CPIO_ODC; |
|
2989 | 2982 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
2990 | 2983 |
ret = cli_scancpio_odc(ctx); |
2991 | 2984 |
break; |
2992 | 2985 |
|
2993 | 2986 |
case CL_TYPE_CPIO_NEWC: |
2994 |
- ctx->container_type = CL_TYPE_CPIO_NEWC; |
|
2995 | 2987 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
2996 | 2988 |
ret = cli_scancpio_newc(ctx, 0); |
2997 | 2989 |
break; |
2998 | 2990 |
|
2999 | 2991 |
case CL_TYPE_CPIO_CRC: |
3000 |
- ctx->container_type = CL_TYPE_CPIO_CRC; |
|
3001 | 2992 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO)) |
3002 | 2993 |
ret = cli_scancpio_newc(ctx, 1); |
3003 | 2994 |
break; |
... | ... |
@@ -3036,7 +3010,6 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
3036 | 3036 |
break; |
3037 | 3037 |
|
3038 | 3038 |
case CL_TYPE_PDF: /* FIXMELIMITS: pdf should be an archive! */ |
3039 |
- ctx->container_type = CL_TYPE_PDF; |
|
3040 | 3039 |
if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF)) |
3041 | 3040 |
ret = cli_scanpdf(ctx, 0); |
3042 | 3041 |
break; |
... | ... |
@@ -3062,19 +3035,16 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
3062 | 3062 |
break; |
3063 | 3063 |
|
3064 | 3064 |
case CL_TYPE_SIS: |
3065 |
- ctx->container_type = CL_TYPE_SIS; |
|
3066 | 3065 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SIS)) |
3067 | 3066 |
ret = cli_scansis(ctx); |
3068 | 3067 |
break; |
3069 | 3068 |
|
3070 | 3069 |
case CL_TYPE_XAR: |
3071 |
- ctx->container_type = CL_TYPE_XAR; |
|
3072 | 3070 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_XAR)) |
3073 | 3071 |
ret = cli_scanxar(ctx); |
3074 | 3072 |
break; |
3075 | 3073 |
|
3076 | 3074 |
case CL_TYPE_PART_HFSPLUS: |
3077 |
- ctx->container_type = CL_TYPE_PART_HFSPLUS; |
|
3078 | 3075 |
if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_HFSPLUS)) |
3079 | 3076 |
ret = cli_scanhfsplus(ctx); |
3080 | 3077 |
break; |
... | ... |
@@ -3099,8 +3069,6 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
3099 | 3099 |
} |
3100 | 3100 |
perf_nested_stop(ctx, PERFT_CONTAINER, PERFT_SCAN); |
3101 | 3101 |
ctx->recursion--; |
3102 |
- ctx->container_type = current_container_type; |
|
3103 |
- ctx->container_size = current_container_size; |
|
3104 | 3102 |
|
3105 | 3103 |
if(ret == CL_VIRUS) { |
3106 | 3104 |
ret = cli_checkfp(hash, hashed_size, ctx); |
... | ... |
@@ -3176,7 +3144,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type) |
3176 | 3176 |
perf_nested_start(ctx, PERFT_SCRIPT, PERFT_SCAN); |
3177 | 3177 |
if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML && (ret != CL_VIRUS || SCAN_ALL) && SCAN_HTML) |
3178 | 3178 |
ret = cli_scanscript(ctx); |
3179 |
- if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX) && ret != CL_VIRUS && (ctx->container_type == CL_TYPE_MAIL || dettype == CL_TYPE_MAIL)) { |
|
3179 |
+ if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX) && ret != CL_VIRUS && (cli_get_container_type(ctx, -1) == CL_TYPE_MAIL || dettype == CL_TYPE_MAIL)) { |
|
3180 | 3180 |
ret = cli_fmap_scandesc(ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL, NULL); |
3181 | 3181 |
} |
3182 | 3182 |
perf_nested_stop(ctx, PERFT_SCRIPT, PERFT_SCAN); |
... | ... |
@@ -3452,8 +3420,10 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned |
3452 | 3452 |
ctx.scanned = scanned; |
3453 | 3453 |
ctx.options = scanoptions; |
3454 | 3454 |
ctx.found_possibly_unwanted = 0; |
3455 |
- ctx.container_type = CL_TYPE_ANY; |
|
3456 |
- ctx.container_size = 0; |
|
3455 |
+ ctx.containers = cli_calloc(sizeof(cli_ctx_container), ctx.engine->maxreclevel + 2); |
|
3456 |
+ if(!ctx.containers) |
|
3457 |
+ return CL_EMEM; |
|
3458 |
+ cli_set_container(&ctx, CL_TYPE_ANY, 0); |
|
3457 | 3459 |
ctx.dconf = (struct cli_dconf *) engine->dconf; |
3458 | 3460 |
ctx.cb_ctx = context; |
3459 | 3461 |
ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2); |
... | ... |
@@ -202,7 +202,12 @@ static int hashpe(const char *filename, unsigned int class, int type) |
202 | 202 |
memset(&ctx, '\0', sizeof(cli_ctx)); |
203 | 203 |
ctx.engine = engine; |
204 | 204 |
ctx.options = CL_SCAN_STDOPT; |
205 |
- ctx.container_type = CL_TYPE_ANY; |
|
205 |
+ ctx.containers = cli_calloc(sizeof(cli_ctx_container), engine->maxreclevel + 2); |
|
206 |
+ if(!ctx.containers) { |
|
207 |
+ cl_engine_free(engine); |
|
208 |
+ return -1; |
|
209 |
+ } |
|
210 |
+ ctx.containers[0].type = CL_TYPE_ANY; |
|
206 | 211 |
ctx.dconf = (struct cli_dconf *) engine->dconf; |
207 | 212 |
ctx.fmap = calloc(sizeof(fmap_t *), 1); |
208 | 213 |
if(!ctx.fmap) { |
... | ... |
@@ -2227,7 +2232,12 @@ static void matchsig(const char *sig, const char *offset, int fd) |
2227 | 2227 |
memset(&ctx, '\0', sizeof(cli_ctx)); |
2228 | 2228 |
ctx.engine = engine; |
2229 | 2229 |
ctx.options = CL_SCAN_STDOPT; |
2230 |
- ctx.container_type = CL_TYPE_ANY; |
|
2230 |
+ ctx.containers = cli_calloc(sizeof(cli_ctx_container), engine->maxreclevel + 2); |
|
2231 |
+ if(!ctx.containers) { |
|
2232 |
+ cl_engine_free(engine); |
|
2233 |
+ return; |
|
2234 |
+ } |
|
2235 |
+ ctx.containers[0].type = CL_TYPE_ANY; |
|
2231 | 2236 |
ctx.dconf = (struct cli_dconf *) engine->dconf; |
2232 | 2237 |
ctx.fmap = calloc(sizeof(fmap_t *), 1); |
2233 | 2238 |
if(!ctx.fmap) { |
... | ... |
@@ -3413,7 +3423,12 @@ static int dumpcerts(const struct optstruct *opts) |
3413 | 3413 |
memset(&ctx, '\0', sizeof(cli_ctx)); |
3414 | 3414 |
ctx.engine = engine; |
3415 | 3415 |
ctx.options = CL_SCAN_STDOPT; |
3416 |
- ctx.container_type = CL_TYPE_ANY; |
|
3416 |
+ ctx.containers = cli_calloc(sizeof(cli_ctx_container), engine->maxreclevel + 2); |
|
3417 |
+ if(!ctx.containers) { |
|
3418 |
+ cl_engine_free(engine); |
|
3419 |
+ return -1; |
|
3420 |
+ } |
|
3421 |
+ ctx.containers[0].type = CL_TYPE_ANY; |
|
3417 | 3422 |
ctx.dconf = (struct cli_dconf *) engine->dconf; |
3418 | 3423 |
ctx.fmap = calloc(sizeof(fmap_t *), 1); |
3419 | 3424 |
if(!ctx.fmap) { |