... | ... |
@@ -44,4 +44,5 @@ void *fmap_need_ptr_once(struct F_MAP *m, void *ptr, size_t len); |
44 | 44 |
void fmap_unneed_off(struct F_MAP *m, size_t at, size_t len); |
45 | 45 |
void fmap_unneed_ptr(struct F_MAP *m, void *ptr, size_t len); |
46 | 46 |
int fmap_readn(struct F_MAP *m, void *dst, size_t at, size_t len); |
47 |
+void *fmap_need_str(struct F_MAP *m, void *ptr, size_t len); |
|
47 | 48 |
#endif |
... | ... |
@@ -24,8 +24,6 @@ |
24 | 24 |
#include "clamav-config.h" |
25 | 25 |
#endif |
26 | 26 |
|
27 |
-#define _XOPEN_SOURCE 500 |
|
28 |
- |
|
29 | 27 |
#include <sys/types.h> |
30 | 28 |
#include <sys/stat.h> |
31 | 29 |
#include <fcntl.h> |
... | ... |
@@ -322,7 +320,7 @@ struct IS_CABSTUFF { |
322 | 322 |
|
323 | 323 |
static void md5str(uint8_t *sum); |
324 | 324 |
static int is_parse_hdr(int desc, cli_ctx *ctx, struct IS_CABSTUFF *c); |
325 |
-static int is_extract_cab(int desc, cli_ctx *ctx, uint64_t off, uint64_t size, uint64_t csize); |
|
325 |
+static int is_extract_cab(cli_ctx *ctx, uint64_t off, uint64_t size, uint64_t csize); |
|
326 | 326 |
|
327 | 327 |
/* Extract the content of older (non-MSI) IS */ |
328 | 328 |
int cli_scanishield(int desc, cli_ctx *ctx, off_t off, size_t sz) { |
... | ... |
@@ -630,7 +628,7 @@ static int is_parse_hdr(int desc, cli_ctx *ctx, struct IS_CABSTUFF *c) { |
630 | 630 |
fmunmap(map); |
631 | 631 |
return CL_EMAXFILES; |
632 | 632 |
} |
633 |
- cabret = is_extract_cab(desc, ctx, file_stream_off + c->cabs[j].off, file_size, file_csize); |
|
633 |
+ cabret = is_extract_cab(ctx, file_stream_off + c->cabs[j].off, file_size, file_csize); |
|
634 | 634 |
} else { |
635 | 635 |
ret = CL_CLEAN; |
636 | 636 |
cli_dbgmsg("is_parse_hdr: stream out of file\n"); |
... | ... |
@@ -686,55 +684,25 @@ static void md5str(uint8_t *sum) { |
686 | 686 |
|
687 | 687 |
#define IS_CABBUFSZ 65536 |
688 | 688 |
|
689 |
-static int is_extract_cab(int desc, cli_ctx *ctx, uint64_t off, uint64_t size, uint64_t csize) { |
|
689 |
+static int is_extract_cab(cli_ctx *ctx, uint64_t off, uint64_t size, uint64_t csize) { |
|
690 | 690 |
uint8_t *inbuf, *outbuf; |
691 | 691 |
char *tempfile; |
692 |
- FILE *in; |
|
693 | 692 |
int ofd, ret = CL_CLEAN; |
694 | 693 |
z_stream z; |
695 | 694 |
uint64_t outsz = 0; |
696 | 695 |
int success = 0; |
696 |
+ struct F_MAP *map = *ctx->fmap; |
|
697 | 697 |
|
698 |
- if((ofd=dup(desc)) < 0) { |
|
699 |
- cli_errmsg("is_extract_cab: dup failed\n"); |
|
700 |
- return CL_EDUP; |
|
701 |
- } |
|
702 |
- if(!(in = fdopen(ofd, "rb"))) { |
|
703 |
- cli_errmsg("is_extract_cab: fdopen failed\n"); |
|
704 |
- close(ofd); |
|
705 |
- return CL_EOPEN; |
|
706 |
- } |
|
707 |
-#if HAVE_FSEEKO |
|
708 |
- if(fseeko(in, (off_t)off, SEEK_SET)) |
|
709 |
-#else |
|
710 |
- if(fseek(in, (long)off, SEEK_SET)) |
|
711 |
-#endif |
|
712 |
- { |
|
713 |
- cli_dbgmsg("is_extract_cab: fseek failed\n"); |
|
714 |
- fclose(in); |
|
715 |
- return CL_ESEEK; |
|
716 |
- } |
|
717 |
- if(!(inbuf = cli_malloc(IS_CABBUFSZ))) { |
|
718 |
- fclose(in); |
|
719 |
- return CL_EMEM; |
|
720 |
- } |
|
721 |
- if(!(outbuf = cli_malloc(IS_CABBUFSZ))) { |
|
722 |
- free(inbuf); |
|
723 |
- fclose(in); |
|
698 |
+ if(!(outbuf = cli_malloc(IS_CABBUFSZ))) |
|
724 | 699 |
return CL_EMEM; |
725 |
- } |
|
700 |
+ |
|
726 | 701 |
if(!(tempfile = cli_gentemp(ctx->engine->tmpdir))) { |
727 |
- free(inbuf); |
|
728 | 702 |
free(outbuf); |
729 |
- fclose(in); |
|
730 |
- return CL_EMEM; |
|
731 | 703 |
} |
732 | 704 |
if((ofd = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR)) < 0) { |
733 | 705 |
cli_errmsg("is_extract_cab: failed to create file %s\n", tempfile); |
734 | 706 |
free(tempfile); |
735 |
- free(inbuf); |
|
736 | 707 |
free(outbuf); |
737 |
- fclose(in); |
|
738 | 708 |
return CL_ECREAT; |
739 | 709 |
} |
740 | 710 |
|
... | ... |
@@ -746,11 +714,12 @@ static int is_extract_cab(int desc, cli_ctx *ctx, uint64_t off, uint64_t size, u |
746 | 746 |
break; |
747 | 747 |
} |
748 | 748 |
csize -= 2; |
749 |
- if(!fread(outbuf, 2, 1, in)) { |
|
749 |
+ if(!(inbuf = fmap_need_off_once(map, off, 2))) { |
|
750 | 750 |
cli_dbgmsg("is_extract_cab: short read for chunk size\n"); |
751 | 751 |
break; |
752 | 752 |
} |
753 |
- chunksz = outbuf[0] | (outbuf[1] << 8); |
|
753 |
+ off += 2; |
|
754 |
+ chunksz = inbuf[0] | (inbuf[1] << 8); |
|
754 | 755 |
if(!chunksz) { |
755 | 756 |
cli_dbgmsg("is_extract_cab: zero sized chunk\n"); |
756 | 757 |
continue; |
... | ... |
@@ -760,10 +729,11 @@ static int is_extract_cab(int desc, cli_ctx *ctx, uint64_t off, uint64_t size, u |
760 | 760 |
break; |
761 | 761 |
} |
762 | 762 |
csize -= chunksz; |
763 |
- if(!fread(inbuf, chunksz, 1, in)) { |
|
763 |
+ if(!(inbuf = fmap_need_off_once(map, off, chunksz))) { |
|
764 | 764 |
cli_dbgmsg("is_extract_cab: short read for chunk\n"); |
765 | 765 |
break; |
766 | 766 |
} |
767 |
+ off += chunksz; |
|
767 | 768 |
memset(&z, 0, sizeof(z)); |
768 | 769 |
inflateInit2(&z, -MAX_WBITS); |
769 | 770 |
z.next_in = (uint8_t *)inbuf; |
... | ... |
@@ -796,8 +766,6 @@ static int is_extract_cab(int desc, cli_ctx *ctx, uint64_t off, uint64_t size, u |
796 | 796 |
inflateEnd(&z); |
797 | 797 |
if(!success) break; |
798 | 798 |
} |
799 |
- fclose(in); |
|
800 |
- free(inbuf); |
|
801 | 799 |
free(outbuf); |
802 | 800 |
if(success) { |
803 | 801 |
if (outsz != size) |