Fix stack overflow with way too many cookies

* src/cookies.c (cookie_header): Use heap instead of stack.
* src/http.c (request_send): Likewise.

If wget has to handle an insanely large amount of cookies (~700,000 on
32 bit systems or ~530,000 on 64 bit systems), the stack is not large
enough to hold these pointers, leading to undefined behaviour according
to POSIX; expect a segmentation fault in real life. ;)

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
This commit is contained in:
Tobias Stoeckmann 2016-08-10 19:09:34 +02:00 committed by Tim Rühsen
parent a9d49e5b15
commit f4aeb41899
3 changed files with 13 additions and 7 deletions

View File

@ -84,6 +84,7 @@ snprintf
socket
spawn-pipe
stdbool
stdint
strcase
strerror_r-posix
strptime

View File

@ -45,6 +45,7 @@ as that of the covered work. */
#include "wget.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -1018,7 +1019,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
struct cookie *cookie;
struct weighed_cookie *outgoing;
int count, i, ocnt;
size_t count, i, ocnt;
char *result;
int result_size, pos;
PREPEND_SLASH (path); /* see cookie_handle_set_cookie */
@ -1032,7 +1033,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
chain_count = find_chains_of_host (jar, host, chains);
/* No cookies for this host. */
if (!chain_count)
if (chain_count <= 0)
return NULL;
cookies_now = time (NULL);
@ -1043,7 +1044,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
/* Count the number of matching cookies. */
count = 0;
for (i = 0; i < chain_count; i++)
for (i = 0; i < (unsigned) chain_count; i++)
for (cookie = chains[i]; cookie; cookie = cookie->next)
if (cookie_matches_url (cookie, host, port, path, secflag, NULL))
++count;
@ -1051,12 +1052,14 @@ cookie_header (struct cookie_jar *jar, const char *host,
return NULL; /* no cookies matched */
/* Allocate the array. */
outgoing = alloca_array (struct weighed_cookie, count);
if (count > SIZE_MAX / sizeof (struct weighed_cookie))
return NULL; /* unable to process so many cookies */
outgoing = xmalloc (count * sizeof (struct weighed_cookie));
/* Fill the array with all the matching cookies from the chains that
match HOST. */
ocnt = 0;
for (i = 0; i < chain_count; i++)
for (i = 0; i < (unsigned) chain_count; i++)
for (cookie = chains[i]; cookie; cookie = cookie->next)
{
int pg;
@ -1111,6 +1114,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
}
}
result[pos++] = '\0';
xfree (outgoing);
assert (pos == result_size);
return result;
}

View File

@ -344,7 +344,7 @@ request_send (const struct request *req, int fd, FILE *warc_tmp)
/* "\r\n\0" */
size += 3;
p = request_string = alloca_array (char, size);
p = request_string = xmalloc (size);
/* Generate the request. */
@ -379,8 +379,9 @@ request_send (const struct request *req, int fd, FILE *warc_tmp)
/* Write a copy of the data to the WARC record. */
int warc_tmp_written = fwrite (request_string, 1, size - 1, warc_tmp);
if (warc_tmp_written != size - 1)
return -2;
write_error = -2;
}
xfree (request_string);
return write_error;
}