Browse code

Tue Feb 10 10:38:08 GMT 2004 (trog) ----------------------------------- * libclamav/ole2_extract.c: Improve error handling

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

Trog authored on 2004/02/10 19:36:38
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Feb 10 10:38:08 GMT 2004 (trog)
2
+-----------------------------------
3
+  * libclamav/ole2_extract.c: Improve error handling
4
+
1 5
 Tue Feb 10 10:21:02 GMT 2004 (njh)
2 6
 ----------------------------------
3 7
   * contrib:	The Windows client now recovers better from errors during
... ...
@@ -179,35 +179,12 @@ int writen(int fd, void *buff, unsigned int count)
179 179
 	return count;
180 180
 }
181 181
 
182
-void print_property_name(char *name, int size)
183
-{
184
-	int i, count=0;
185
-
186
-	if (*name == 0 || size == 0) {
187
-		cli_dbgmsg("[no name]                           ");
188
-		return;
189
-	}
190
-	/* size-2 to ignore trailing NULL */
191
-	for (i=0 ; i<size-2; i+=2) {
192
-		if (isprint(name[i])) {
193
-			cli_dbgmsg("%c", name[i]);
194
-			count++;
195
-		} else {
196
-			cli_dbgmsg("_%d_", name[i]);
197
-			count += 3;
198
-		}
199
-	}
200
-	for (i=0 ; i < (34-count) ; i++) {
201
-		cli_dbgmsg(" ");
202
-	}
203
-}
204
-
205 182
 char *get_property_name(char *name, int size)
206 183
 {
207 184
 	int i, j;
208 185
 	char *newname;
209 186
 
210
-	if (*name == 0 || size == 0) {
187
+	if (*name == 0 || size == 0 || size > 64) {
211 188
 		return NULL;
212 189
 	}
213 190
 
... ...
@@ -235,10 +212,27 @@ char *get_property_name(char *name, int size)
235 235
 	}
236 236
 	return newname;
237 237
 }
238
+                                                                                                                                              
239
+void print_property_name(char *pname, int size)
240
+{
241
+        char *name;
242
+                                                                                                                                              
243
+        name = get_property_name(pname, size);
244
+        if (!name) {
245
+                return;
246
+        }
247
+        cli_dbgmsg("%34s", name);
248
+        free(name);
249
+        return;
250
+}
238 251
 
239 252
 void print_ole2_property(property_t *property)
240 253
 {
241
-	//print_property_name(property->name, property->name_size);
254
+	if (property->name_size > 64) {
255
+                cli_dbgmsg("[err name len: %d]\n", property->name_size);
256
+                return;
257
+        }
258
+	print_property_name(property->name, property->name_size);
242 259
 	switch (property->type) {
243 260
 	case 2:
244 261
 		cli_dbgmsg(" [file]");
... ...
@@ -443,10 +437,10 @@ int32_t ole2_get_sbat_data_block(int fd, ole2_header_t *hdr, void *buff, int32_t
443 443
 /* Read the property tree.
444 444
    It is read as just an array rather than a tree */
445 445
 void ole2_read_property_tree(int fd, ole2_header_t *hdr, const char *dir,
446
-				void (*handler)(int fd, ole2_header_t *hdr, property_t *prop, const char *dir))
446
+				int (*handler)(int fd, ole2_header_t *hdr, property_t *prop, const char *dir))
447 447
 {
448 448
 	property_t prop_block[4];
449
-	int32_t index, current_block;
449
+	int32_t index, current_block, count=0;
450 450
 	
451 451
 	current_block = hdr->prop_start;
452 452
 
... ...
@@ -468,14 +462,26 @@ void ole2_read_property_tree(int fd, ole2_header_t *hdr, const char *dir,
468 468
 				prop_block[index].mod_highdate = ole2_endian_convert_32(prop_block[index].mod_highdate);
469 469
 				prop_block[index].start_block = ole2_endian_convert_32(prop_block[index].start_block);
470 470
 				prop_block[index].size = ole2_endian_convert_32(prop_block[index].size);
471
+				if (prop_block[index].type > 5) {
472
+					cli_dbgmsg("ERROR: invalid property type: %d\n", prop_block[index].type);
473
+					return;
474
+				}
471 475
 				if (prop_block[index].type == 5) {
472 476
 					hdr->sbat_root_start = prop_block[index].start_block;
473 477
 				}
474 478
 				print_ole2_property(&prop_block[index]);
475
-				handler(fd, hdr, &prop_block[index], dir);
479
+				if (!handler(fd, hdr, &prop_block[index], dir)) {
480
+					cli_dbgmsg("ERROR: handler failed\n");
481
+					return;
482
+				}
476 483
 			}
477 484
 		}
478 485
 		current_block = ole2_get_next_block_number(fd, hdr, current_block);
486
+		/* Loop detection */
487
+		if (++count > 100000) {
488
+			cli_dbgmsg("ERROR: loop detected\n");
489
+			return;
490
+		}
479 491
 	}
480 492
 	return;
481 493
 }
... ...
@@ -484,13 +490,13 @@ void ole2_read_property_tree(int fd, ole2_header_t *hdr, const char *dir,
484 484
    These are called for each entry in the container (property tree) */
485 485
 
486 486
 /* Null Handler - doesn't do anything */
487
-void handler_null(int fd, ole2_header_t *hdr, property_t *prop, const char *dir)
487
+int handler_null(int fd, ole2_header_t *hdr, property_t *prop, const char *dir)
488 488
 {
489
-	return;
489
+	return TRUE;
490 490
 }
491 491
 
492 492
 /* Write file Handler - write the contents of the entry to a file */
493
-void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char *dir)
493
+int handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char *dir)
494 494
 {
495 495
 	unsigned char buff[(1 << hdr->log2_big_block_size)];
496 496
 	int32_t current_block, ofd, len, offset;
... ...
@@ -498,7 +504,12 @@ void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char
498 498
 
499 499
 	if (prop->type != 2) {
500 500
 		// Not a file
501
-		return;
501
+		return TRUE;
502
+	}
503
+
504
+	if (prop->name_size > 64) {
505
+		cli_dbgmsg("\nERROR: property name too long: %d\n", prop->name_size);
506
+		return FALSE;
502 507
 	}
503 508
 
504 509
 	if (! (name = get_property_name(prop->name, prop->name_size))) {
... ...
@@ -506,9 +517,9 @@ void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char
506 506
 		int i;
507 507
                                                                                                                             
508 508
 		i = lseek(fd, 0, SEEK_CUR);
509
-		name = malloc(11);
509
+		name = (char *) cli_malloc(11);
510 510
 		if (!name) {
511
-			return;
511
+			return FALSE;
512 512
 		}
513 513
 		snprintf(name, 10, "%.10d", i + (int) prop);
514 514
 	}
... ...
@@ -519,7 +530,7 @@ void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char
519 519
 
520 520
 	ofd = open(newname, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
521 521
 	if (ofd < 0) {
522
-		return;
522
+		return FALSE;
523 523
 	}
524 524
 	free(newname);
525 525
 	current_block = prop->start_block;
... ...
@@ -531,13 +542,13 @@ void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char
531 531
 			if (!ole2_get_sbat_data_block(fd, hdr, &buff, current_block)) {
532 532
 				cli_dbgmsg("ole2_get_sbat_data_block failed\n");
533 533
 				close(ofd);
534
-				return;
534
+				return FALSE;
535 535
 			}
536 536
 			// buff now contains the block with 8 small blocks in it
537 537
 			offset = 64 * (current_block % 8);
538 538
 			if (writen(ofd, &buff[offset], MIN(len,64)) != MIN(len,64)) {
539 539
 				close(ofd);
540
-				return;
540
+				return FALSE;
541 541
 			}
542 542
 
543 543
 			len -= MIN(len,64);
... ...
@@ -546,12 +557,12 @@ void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char
546 546
 			// Big block file
547 547
 			if (!ole2_read_block(fd, hdr, &buff, current_block)) {
548 548
 				close(ofd);
549
-				return;
549
+				return FALSE;
550 550
 			}
551 551
 			if (writen(ofd, &buff, MIN(len,(1 << hdr->log2_big_block_size))) !=
552 552
 							MIN(len,(1 << hdr->log2_big_block_size))) {
553 553
 				close(ofd);
554
-				return;
554
+				return FALSE;
555 555
 			}
556 556
 
557 557
 			current_block = ole2_get_next_block_number(fd, hdr, current_block);
... ...
@@ -559,7 +570,7 @@ void handler_writefile(int fd, ole2_header_t *hdr, property_t *prop, const char
559 559
 		}
560 560
 	}
561 561
 	close(ofd);
562
-	return;
562
+	return TRUE;
563 563
 }
564 564
 
565 565
 int ole2_read_header(int fd, ole2_header_t *hdr)