diff options
author | Christian Grothoff <christian@grothoff.org> | 2020-06-28 21:55:56 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2020-06-28 21:55:56 +0200 |
commit | a110ae6276660bee3caab30e9ff3f12f85cf3241 (patch) | |
tree | cc959ef6b757b336978802f18b4cf420563a4a48 /src/microhttpd | |
parent | 0d771f770e6c444cfee7f4f588620e9c8b934d97 (diff) | |
download | libmicrohttpd-a110ae6276660bee3caab30e9ff3f12f85cf3241.tar.gz libmicrohttpd-a110ae6276660bee3caab30e9ff3f12f85cf3241.zip |
fix buffer overflow and add testv0.9.71
Diffstat (limited to 'src/microhttpd')
-rw-r--r-- | src/microhttpd/postprocessor.c | 18 | ||||
-rw-r--r-- | src/microhttpd/test_postprocessor.c | 66 |
2 files changed, 80 insertions, 4 deletions
diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c index 8848b306..1eb33ed6 100644 --- a/src/microhttpd/postprocessor.c +++ b/src/microhttpd/postprocessor.c | |||
@@ -137,8 +137,7 @@ struct MHD_PostProcessor | |||
137 | void *cls; | 137 | void *cls; |
138 | 138 | ||
139 | /** | 139 | /** |
140 | * Encoding as given by the headers of the | 140 | * Encoding as given by the headers of the connection. |
141 | * connection. | ||
142 | */ | 141 | */ |
143 | const char *encoding; | 142 | const char *encoding; |
144 | 143 | ||
@@ -590,7 +589,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, | |||
590 | pp->state = PP_Error; | 589 | pp->state = PP_Error; |
591 | break; | 590 | break; |
592 | case PP_Callback: | 591 | case PP_Callback: |
593 | if ( (pp->buffer_pos + (end_key - start_key) > | 592 | if ( (pp->buffer_pos + (end_key - start_key) >= |
594 | pp->buffer_size) || | 593 | pp->buffer_size) || |
595 | (pp->buffer_pos + (end_key - start_key) < | 594 | (pp->buffer_pos + (end_key - start_key) < |
596 | pp->buffer_pos) ) | 595 | pp->buffer_pos) ) |
@@ -640,6 +639,11 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, | |||
640 | { | 639 | { |
641 | if (NULL == end_key) | 640 | if (NULL == end_key) |
642 | end_key = &post_data[poff]; | 641 | end_key = &post_data[poff]; |
642 | if (pp->buffer_pos + (end_key - start_key) >= pp->buffer_size) | ||
643 | { | ||
644 | pp->state = PP_Error; | ||
645 | return MHD_NO; | ||
646 | } | ||
643 | memcpy (&kbuf[pp->buffer_pos], | 647 | memcpy (&kbuf[pp->buffer_pos], |
644 | start_key, | 648 | start_key, |
645 | end_key - start_key); | 649 | end_key - start_key); |
@@ -667,6 +671,11 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, | |||
667 | last_escape); | 671 | last_escape); |
668 | pp->must_ikvi = false; | 672 | pp->must_ikvi = false; |
669 | } | 673 | } |
674 | if (PP_Error == pp->state) | ||
675 | { | ||
676 | /* State in error, returning failure */ | ||
677 | return MHD_NO; | ||
678 | } | ||
670 | return MHD_YES; | 679 | return MHD_YES; |
671 | } | 680 | } |
672 | 681 | ||
@@ -1428,7 +1437,8 @@ MHD_destroy_post_processor (struct MHD_PostProcessor *pp) | |||
1428 | the post-processing may have been interrupted | 1437 | the post-processing may have been interrupted |
1429 | at any stage */ | 1438 | at any stage */ |
1430 | if ( (pp->xbuf_pos > 0) || | 1439 | if ( (pp->xbuf_pos > 0) || |
1431 | (pp->state != PP_Done) ) | 1440 | ( (pp->state != PP_Done) && |
1441 | (pp->state != PP_Init) ) ) | ||
1432 | ret = MHD_NO; | 1442 | ret = MHD_NO; |
1433 | else | 1443 | else |
1434 | ret = MHD_YES; | 1444 | ret = MHD_YES; |
diff --git a/src/microhttpd/test_postprocessor.c b/src/microhttpd/test_postprocessor.c index e70171cc..b62e7ff9 100644 --- a/src/microhttpd/test_postprocessor.c +++ b/src/microhttpd/test_postprocessor.c | |||
@@ -451,6 +451,71 @@ test_empty_value (void) | |||
451 | } | 451 | } |
452 | 452 | ||
453 | 453 | ||
454 | static enum MHD_Result | ||
455 | value_checker2 (void *cls, | ||
456 | enum MHD_ValueKind kind, | ||
457 | const char *key, | ||
458 | const char *filename, | ||
459 | const char *content_type, | ||
460 | const char *transfer_encoding, | ||
461 | const char *data, | ||
462 | uint64_t off, | ||
463 | size_t size) | ||
464 | { | ||
465 | return MHD_YES; | ||
466 | } | ||
467 | |||
468 | |||
469 | static int | ||
470 | test_overflow () | ||
471 | { | ||
472 | struct MHD_Connection connection; | ||
473 | struct MHD_HTTP_Header header; | ||
474 | struct MHD_PostProcessor *pp; | ||
475 | size_t i; | ||
476 | size_t j; | ||
477 | size_t delta; | ||
478 | char *buf; | ||
479 | |||
480 | memset (&connection, 0, sizeof (struct MHD_Connection)); | ||
481 | memset (&header, 0, sizeof (struct MHD_HTTP_Header)); | ||
482 | connection.headers_received = &header; | ||
483 | header.header = MHD_HTTP_HEADER_CONTENT_TYPE; | ||
484 | header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED; | ||
485 | header.header_size = strlen (header.header); | ||
486 | header.value_size = strlen (header.value); | ||
487 | header.kind = MHD_HEADER_KIND; | ||
488 | for (i = 128; i < 1024 * 1024; i += 1024) | ||
489 | { | ||
490 | pp = MHD_create_post_processor (&connection, | ||
491 | 1024, | ||
492 | &value_checker2, | ||
493 | NULL); | ||
494 | buf = malloc (i); | ||
495 | if (NULL == buf) | ||
496 | return 1; | ||
497 | memset (buf, 'A', i); | ||
498 | buf[i / 2] = '='; | ||
499 | delta = 1 + (MHD_random_ () % (i - 1)); | ||
500 | j = 0; | ||
501 | while (j < i) | ||
502 | { | ||
503 | if (j + delta > i) | ||
504 | delta = i - j; | ||
505 | if (MHD_NO == | ||
506 | MHD_post_process (pp, | ||
507 | &buf[j], | ||
508 | delta)) | ||
509 | break; | ||
510 | j += delta; | ||
511 | } | ||
512 | free (buf); | ||
513 | MHD_destroy_post_processor (pp); | ||
514 | } | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | |||
454 | int | 519 | int |
455 | main (int argc, char *const *argv) | 520 | main (int argc, char *const *argv) |
456 | { | 521 | { |
@@ -463,6 +528,7 @@ main (int argc, char *const *argv) | |||
463 | errorCount += test_multipart (); | 528 | errorCount += test_multipart (); |
464 | errorCount += test_nested_multipart (); | 529 | errorCount += test_nested_multipart (); |
465 | errorCount += test_empty_value (); | 530 | errorCount += test_empty_value (); |
531 | errorCount += test_overflow (); | ||
466 | if (errorCount != 0) | 532 | if (errorCount != 0) |
467 | fprintf (stderr, "Error (code: %u)\n", errorCount); | 533 | fprintf (stderr, "Error (code: %u)\n", errorCount); |
468 | return errorCount != 0; /* 0 == pass */ | 534 | return errorCount != 0; /* 0 == pass */ |