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... | ... |
@@ -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) |