mirror of
https://github.com/mirror/wget.git
synced 2025-01-26 20:30:40 +08:00
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:
parent
a9d49e5b15
commit
f4aeb41899
@ -84,6 +84,7 @@ snprintf
|
||||
socket
|
||||
spawn-pipe
|
||||
stdbool
|
||||
stdint
|
||||
strcase
|
||||
strerror_r-posix
|
||||
strptime
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user