Browse code

detect block list loop (bb#466)

git-svn: trunk@3078

Tomasz Kojm authored on 2007/05/30 01:17:27
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue May 29 17:42:12 CEST 2007 (tk)
2
+----------------------------------
3
+  * libclamav/ole2_extract.c: detect block list loop (bb#466), patch from Trog
4
+
1 5
 Tue May 29 17:07:08 CEST 2007 (edwin)
2 6
 ----------------------------------
3 7
   * libclamav/phishcheck.c: bb #497
... ...
@@ -1,7 +1,7 @@
1 1
 /*
2 2
  *  Extract component parts of OLE2 files (e.g. MS Office Documents)
3 3
  *
4
- *  Copyright (C) 2004 trog@uncon.org
4
+ *  Copyright (C) 2004-2007 trog@uncon.org
5 5
  *
6 6
  *  This code is based on the OpenOffice and libgsf sources.
7 7
  *                  
... ...
@@ -588,6 +588,7 @@ static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const
588 588
 	unsigned char *buff;
589 589
 	int32_t current_block, ofd, len, offset;
590 590
 	char *name, *newname;
591
+	bitset_t *blk_bitset;
591 592
 
592 593
 	if (prop->type != 2) {
593 594
 		/* Not a file */
... ...
@@ -638,14 +639,36 @@ static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const
638 638
 		close(ofd);
639 639
 		return FALSE;
640 640
 	}
641
-
641
+	
642
+	blk_bitset = cli_bitset_init();
643
+	if (!blk_bitset) {
644
+		cli_errmsg("ERROR [handler_writefile]: init bitset failed\n");
645
+		close(ofd);
646
+		return FALSE;
647
+	}
642 648
 	while((current_block >= 0) && (len > 0)) {
649
+		/* Check we aren't in a loop */
650
+		if (cli_bitset_test(blk_bitset, (unsigned long) current_block)) {
651
+			/* Loop in block list */
652
+			cli_dbgmsg("OLE2: Block list loop detected\n");
653
+			close(ofd);
654
+			free(buff);
655
+			cli_bitset_free(blk_bitset);
656
+			return FALSE;
657
+		}
658
+		if (!cli_bitset_set(blk_bitset, (unsigned long) current_block)) {
659
+			close(ofd);
660
+			free(buff);
661
+			cli_bitset_free(blk_bitset);
662
+			return FALSE;
663
+		}			
643 664
 		if (prop->size < (int64_t)hdr->sbat_cutoff) {
644 665
 			/* Small block file */
645 666
 			if (!ole2_get_sbat_data_block(fd, hdr, buff, current_block)) {
646 667
 				cli_dbgmsg("ole2_get_sbat_data_block failed\n");
647 668
 				close(ofd);
648 669
 				free(buff);
670
+				cli_bitset_free(blk_bitset);
649 671
 				return FALSE;
650 672
 			}
651 673
 			/* buff now contains the block with 8 small blocks in it */
... ...
@@ -653,6 +676,7 @@ static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const
653 653
 			if (cli_writen(ofd, &buff[offset], MIN(len,64)) != MIN(len,64)) {
654 654
 				close(ofd);
655 655
 				free(buff);
656
+				cli_bitset_free(blk_bitset);
656 657
 				return FALSE;
657 658
 			}
658 659
 
... ...
@@ -663,12 +687,14 @@ static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const
663 663
 			if (!ole2_read_block(fd, hdr, buff, current_block)) {
664 664
 				close(ofd);
665 665
 				free(buff);
666
+				cli_bitset_free(blk_bitset);
666 667
 				return FALSE;
667 668
 			}
668 669
 			if (cli_writen(ofd, buff, MIN(len,(1 << hdr->log2_big_block_size))) !=
669 670
 							MIN(len,(1 << hdr->log2_big_block_size))) {
670 671
 				close(ofd);
671 672
 				free(buff);
673
+				cli_bitset_free(blk_bitset);
672 674
 				return FALSE;
673 675
 			}
674 676
 
... ...
@@ -678,6 +704,7 @@ static int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const
678 678
 	}
679 679
 	close(ofd);
680 680
 	free(buff);
681
+	cli_bitset_free(blk_bitset);
681 682
 	return TRUE;
682 683
 }
683 684