Browse code

* libclamav/vba_extract.c: dumb down the PowerPoint parser to Microsofts level. * libclamav/ole2_extract.c: check against recursion limits

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@644 77e5149b-7576-45b1-b177-96237e5ba77b

Trog authored on 2004/06/30 21:28:17
Showing 3 changed files
... ...
@@ -1,3 +1,9 @@
1
+Wed Jun 30 13:24:56 BST 2004 (trog)
2
+-----------------------------------
3
+  * libclamav/vba_extract.c: dumb down the PowerPoint parser to Microsofts level.
4
+
5
+  * libclamav/ole2_extract.c: check against recursion limits
6
+
1 7
 Tue Jun 29 23:24:44 CEST 2004 (tk)
2 8
 ----------------------------------
3 9
   * doc: update
... ...
@@ -469,11 +469,16 @@ static void ole2_walk_property_tree(int fd, ole2_header_t *hdr, const char *dir,
469 469
 		return;
470 470
 	}
471 471
 	
472
-	if(limits && limits->maxfiles && (*file_count > limits->maxfiles)) {
472
+	if (limits && limits->maxfiles && (*file_count > limits->maxfiles)) {
473 473
 		cli_dbgmsg("OLE2: File limit reached (max: %d)\n", limits->maxfiles);
474 474
 		return;
475 475
 	}
476 476
 	
477
+	if (limits && limits->maxreclevel && (rec_level > limits->maxreclevel)) {
478
+		cli_dbgmsg("OLE2: Recursion limit reached (max: %d)\n", limits->maxreclevel);
479
+		return;
480
+	}
481
+	
477 482
 	index = prop_index / 4;
478 483
 	for (i=0 ; i < index ; i++) {
479 484
 		current_block = ole2_get_next_block_number(fd, hdr, current_block);
... ...
@@ -975,8 +975,93 @@ static int ppt_unlzw(const char *dir, int fd, uint32_t length)
975 975
 	return TRUE;
976 976
 }
977 977
 
978
+static char *ppt_stream_iter(int fd)
979
+{
980
+	atom_header_t atom_header;
981
+	uint32_t ole_id;
982
+	char *tmpdir, *out_dir;
983
+	
984
+	/* Create a directory to store the extracted OLE2 objects */
985
+	tmpdir = getenv("TMPDIR");
986
+
987
+	if(tmpdir == NULL)
988
+#ifdef P_tmpdir
989
+		tmpdir = P_tmpdir;
990
+#else
991
+		tmpdir = "/tmp";
992
+#endif
993
+
994
+	/* generate the temporary directory */
995
+	out_dir = cl_gentemp(tmpdir);
996
+	if(mkdir(out_dir, 0700)) {
997
+	    printf("ScanOLE2 -> Can't create temporary directory %s\n", out_dir);
998
+	    close(fd);
999
+	    return NULL;
1000
+	}
1001
+
1002
+	while (1) {
1003
+		if (!ppt_read_atom_header(fd, &atom_header)) {
1004
+			break;
1005
+		}
1006
+		ppt_print_atom_header(&atom_header);
1007
+
1008
+		if (atom_header.type == 0x1011) {
1009
+			if (cli_readn(fd, &ole_id, 4) != 4) {
1010
+				cli_dbgmsg("read ole_id failed\n");
1011
+				cli_rmdirs(out_dir);
1012
+				free(out_dir);
1013
+				return NULL;
1014
+			}
1015
+			ole_id = vba_endian_convert_32(ole_id, FALSE);
1016
+			cli_dbgmsg("OleID: %d, length: %d\n",
1017
+					ole_id, atom_header.length-4);
1018
+			if (!ppt_unlzw(out_dir, fd, atom_header.length-4)) {
1019
+				cli_dbgmsg("ppt_unlzw failed\n");
1020
+				cli_rmdirs(out_dir);
1021
+				free(out_dir);
1022
+				return NULL;
1023
+			}
1024
+
1025
+		} else {
1026
+			if (lseek(fd, atom_header.length, SEEK_CUR) == -1 ) {
1027
+				break;
1028
+			}
1029
+		}
1030
+	}
1031
+	return out_dir;
1032
+}
1033
+
978 1034
 char *ppt_vba_read(const char *dir)
979 1035
 {
1036
+	char *fullname, *out_dir;
1037
+	int fd;
1038
+	atom_header_t atom_header;
1039
+	uint32_t ole_id;
1040
+
1041
+	fullname = (char *) cli_malloc(strlen(dir) + 21);
1042
+	if (!fullname) {
1043
+		return NULL;
1044
+	}
1045
+	sprintf(fullname, "%s/PowerPoint Document", dir);
1046
+	fd = open(fullname, O_RDONLY);
1047
+	free(fullname);
1048
+	if (fd == -1) {
1049
+		cli_dbgmsg("Open  PowerPoint Document failed\n");
1050
+		return NULL;
1051
+	}
1052
+	
1053
+	out_dir = ppt_stream_iter(fd);
1054
+	close(fd);
1055
+	return out_dir;
1056
+}
1057
+	
1058
+	
1059
+/* Strictly speaking, the method below is the correct way to access the
1060
+	componenets of a PowerPoint file. However, it appears Microsoft
1061
+	don't do it that way.
1062
+	
1063
+char *ppt_vba_read_strict(const char *dir)
1064
+{
980 1065
 	ppt_currentuser_t ppt_current_user;
981 1066
 	ppt_useredit_t ppt_useredit;
982 1067
 	uint32_t *persist_dir;
... ...
@@ -1014,9 +1099,10 @@ char *ppt_vba_read(const char *dir)
1014 1014
 	fd = open(fullname, O_RDONLY);
1015 1015
 	free(fullname);
1016 1016
 	if (fd == -1) {
1017
-		cli_dbgmsg("Open Current User failed\n");
1017
+		cli_dbgmsg("Open PowerPoint Document failed\n");
1018 1018
 		return NULL;
1019 1019
 	}
1020
+		
1020 1021
 	if (lseek(fd, ppt_current_user.current_edit_offset, SEEK_SET) !=
1021 1022
 					ppt_current_user.current_edit_offset) {
1022 1023
 		cli_dbgmsg("lseek cli_ppt_vbaread failed\n");
... ...
@@ -1024,7 +1110,6 @@ char *ppt_vba_read(const char *dir)
1024 1024
 		return FALSE;
1025 1025
 	}
1026 1026
 
1027
-	/* Create a directory to store the extracted OLE2 objects */
1028 1027
 	tmpdir = getenv("TMPDIR");
1029 1028
 
1030 1029
 	if(tmpdir == NULL)
... ...
@@ -1034,7 +1119,6 @@ char *ppt_vba_read(const char *dir)
1034 1034
 		tmpdir = "/tmp";
1035 1035
 #endif
1036 1036
 
1037
-	/* generate the temporary directory */
1038 1037
 	out_dir = cl_gentemp(tmpdir);
1039 1038
 	if(mkdir(out_dir, 0700)) {
1040 1039
 	    printf("ScanOLE2 -> Can't create temporary directory %s\n", dir);
... ...
@@ -1107,6 +1191,8 @@ char *ppt_vba_read(const char *dir)
1107 1107
 	close(fd);
1108 1108
 	return out_dir;
1109 1109
 }	
1110
+*/
1111
+
1110 1112
 
1111 1113
 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
1112 1114
 /* Code to extract Word6 macros