Browse code

Removing unRAR SFX Check from scanners.c. Flawed feature was skipping scans of files in RAR archives that had the same CRC in the RAR file entry header as a previously scanned entry. Archives CRC's cannot be trusted. Removing the SFX Check eliminated false negatives in regression testing.

Micah Snyder authored on 2018/09/25 04:01:22
Showing 2 changed files
... ...
@@ -961,10 +961,25 @@ cl_error_t cli_gentempfd_with_prefix(const char* dir, char* prefix, char** name,
961 961
      * errors
962 962
      */
963 963
     if (*fd == -1) {
964
-        cli_errmsg("cli_gentempfd_with_prefix: Can't create temporary file %s: %s\n", *name, strerror(errno));
965
-        free(*name);
966
-        *name = NULL;
967
-        return CL_ECREAT;
964
+        if ((EILSEQ == errno) || (EINVAL == errno) || (ENAMETOOLONG == errno)) {
965
+            cli_dbgmsg("cli_gentempfd_with_prefix: Can't create temp file using prefix. Using a randomly generated name instead.\n");
966
+            free(*name);
967
+            *name = cli_gentemp(dir);
968
+            if (!*name)
969
+                return CL_EMEM;
970
+            *fd = open(*name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_EXCL, S_IRWXU);
971
+            if (*fd == -1) {
972
+                cli_errmsg("cli_gentempfd_with_prefix: Can't create temporary file %s: %s\n", *name, strerror(errno));
973
+                free(*name);
974
+                *name = NULL;
975
+                return CL_ECREAT;
976
+            }
977
+        } else {
978
+            cli_errmsg("cli_gentempfd_with_prefix: Can't create temporary file %s: %s\n", *name, strerror(errno));
979
+            free(*name);
980
+            *name = NULL;
981
+            return CL_ECREAT;
982
+        }
968 983
     }
969 984
 
970 985
     return CL_SUCCESS;
... ...
@@ -227,23 +227,13 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx)
227 227
  * @param metadata  unrar metadata structure
228 228
  * @param ctx       scanning context structure
229 229
  * @param files     
230
- * @param sfx_check 
231
- * @return cl_error_t  Returns CL_CLEAN if nothing found, CL_VIRUS if something found, CL_EUNPACK if encrypted, or CL_BREAK to end extraction.
230
+ * @return cl_error_t  Returns CL_CLEAN if nothing found, CL_VIRUS if something found, CL_EUNPACK if encrypted.
232 231
  */
233
-static cl_error_t cli_unrar_scanmetadata(unrar_metadata_t* metadata, cli_ctx* ctx, unsigned int files, uint32_t* sfx_check)
232
+static cl_error_t cli_unrar_scanmetadata(unrar_metadata_t* metadata, cli_ctx* ctx, unsigned int files)
234 233
 {
235 234
     cl_error_t status = CL_CLEAN;
236 235
     int virus_found = 0;
237 236
 
238
-    if (files == 1 && sfx_check) {
239
-        if (*sfx_check == metadata->crc) {
240
-            status = CL_BREAK; /* break extract loop */
241
-            goto done;
242
-        } else {
243
-            *sfx_check = metadata->crc;
244
-        }
245
-    }
246
-
247 237
     cli_dbgmsg("RAR: %s, crc32: 0x%x, encrypted: %u, compressed: %u, normal: %u, method: %u, ratio: %u\n",
248 238
         metadata->filename, metadata->crc, metadata->encrypted, (unsigned int)metadata->pack_size,
249 239
         (unsigned int)metadata->unpack_size, metadata->method,
... ...
@@ -261,7 +251,7 @@ done:
261 261
     return status;
262 262
 }
263 263
 
264
-static cl_error_t cli_scanrar(const char *filepath, int desc, cli_ctx* ctx, uint32_t* sfx_check)
264
+static cl_error_t cli_scanrar(const char *filepath, int desc, cli_ctx* ctx)
265 265
 {
266 266
     cl_error_t status = CL_EPARSE;
267 267
     cl_unrar_error_t unrar_ret = UNRAR_ERR;
... ...
@@ -414,7 +404,7 @@ static cl_error_t cli_scanrar(const char *filepath, int desc, cli_ctx* ctx, uint
414 414
             /*
415 415
             * Scan the metadata for the file in question since the content was clean, or we're running in all-match.
416 416
             */
417
-            status = cli_unrar_scanmetadata(&metadata, ctx, file_count, sfx_check);
417
+            status = cli_unrar_scanmetadata(&metadata, ctx, file_count);
418 418
             if ((status == CL_VIRUS) && SCAN_ALLMATCHES) {
419 419
                 status = CL_CLEAN;
420 420
                 viruses_found++;
... ...
@@ -601,15 +591,13 @@ done:
601 601
     return status;
602 602
 }
603 603
 
604
-static int cli_scanarj(cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check)
604
+static int cli_scanarj(cli_ctx *ctx, off_t sfx_offset)
605 605
 {
606 606
     int ret = CL_CLEAN, rc, file = 0;
607 607
     arj_metadata_t metadata;
608 608
     char *dir;
609 609
     int virus_found = 0;
610 610
 
611
-    UNUSEDPARAM(sfx_check);
612
-
613 611
     cli_dbgmsg("in cli_scanarj()\n");
614 612
 
615 613
     memset(&metadata, 0, sizeof(arj_metadata_t));
... ...
@@ -2614,7 +2602,6 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
2614 2614
     {
2615 2615
         perf_nested_start(ctx, PERFT_RAWTYPENO, PERFT_SCAN);
2616 2616
         ctx->recursion++;
2617
-        lastrar = 0xdeadbeef;
2618 2617
         fpt = ftoffset;
2619 2618
 
2620 2619
         while (fpt)
... ...
@@ -2694,7 +2681,7 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
2694 2694
                         }
2695 2695
 
2696 2696
                         /* scan file */
2697
-                        nret = cli_scanrar(filepath, fd, ctx, &lastrar);
2697
+                        nret = cli_scanrar(filepath, fd, ctx);
2698 2698
 
2699 2699
                         if (tmpfd != -1)
2700 2700
                         {
... ...
@@ -2740,7 +2727,7 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
2740 2740
                         size_t csize = map->len - fpt->offset; /* not precise */
2741 2741
                         cli_set_container(ctx, CL_TYPE_ARJ, csize);
2742 2742
                         cli_dbgmsg("ARJ-SFX signature found at %u\n", (unsigned int)fpt->offset);
2743
-                        nret = cli_scanarj(ctx, fpt->offset, &lastrar);
2743
+                        nret = cli_scanarj(ctx, fpt->offset);
2744 2744
                     }
2745 2745
                     break;
2746 2746
 
... ...
@@ -3377,7 +3364,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
3377 3377
             }
3378 3378
 
3379 3379
             /* scan file */
3380
-            ret = cli_scanrar(filepath, fd, ctx, NULL);
3380
+            ret = cli_scanrar(filepath, fd, ctx);
3381 3381
 
3382 3382
             if (tmpfd != -1) {
3383 3383
                 /* If dumped tempfile, need to cleanup */
... ...
@@ -3456,7 +3443,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
3456 3456
 
3457 3457
     case CL_TYPE_ARJ:
3458 3458
         if (SCAN_PARSE_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ))
3459
-            ret = cli_scanarj(ctx, 0, NULL);
3459
+            ret = cli_scanarj(ctx, 0);
3460 3460
         break;
3461 3461
 
3462 3462
     case CL_TYPE_NULSFT: