mirror of
https://github.com/mirror/wget.git
synced 2025-02-05 01:01:00 +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
|
socket
|
||||||
spawn-pipe
|
spawn-pipe
|
||||||
stdbool
|
stdbool
|
||||||
|
stdint
|
||||||
strcase
|
strcase
|
||||||
strerror_r-posix
|
strerror_r-posix
|
||||||
strptime
|
strptime
|
||||||
|
@ -45,6 +45,7 @@ as that of the covered work. */
|
|||||||
|
|
||||||
#include "wget.h"
|
#include "wget.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -1018,7 +1019,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
|
|||||||
|
|
||||||
struct cookie *cookie;
|
struct cookie *cookie;
|
||||||
struct weighed_cookie *outgoing;
|
struct weighed_cookie *outgoing;
|
||||||
int count, i, ocnt;
|
size_t count, i, ocnt;
|
||||||
char *result;
|
char *result;
|
||||||
int result_size, pos;
|
int result_size, pos;
|
||||||
PREPEND_SLASH (path); /* see cookie_handle_set_cookie */
|
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);
|
chain_count = find_chains_of_host (jar, host, chains);
|
||||||
|
|
||||||
/* No cookies for this host. */
|
/* No cookies for this host. */
|
||||||
if (!chain_count)
|
if (chain_count <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
cookies_now = time (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 the number of matching cookies. */
|
||||||
count = 0;
|
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)
|
for (cookie = chains[i]; cookie; cookie = cookie->next)
|
||||||
if (cookie_matches_url (cookie, host, port, path, secflag, NULL))
|
if (cookie_matches_url (cookie, host, port, path, secflag, NULL))
|
||||||
++count;
|
++count;
|
||||||
@ -1051,12 +1052,14 @@ cookie_header (struct cookie_jar *jar, const char *host,
|
|||||||
return NULL; /* no cookies matched */
|
return NULL; /* no cookies matched */
|
||||||
|
|
||||||
/* Allocate the array. */
|
/* 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
|
/* Fill the array with all the matching cookies from the chains that
|
||||||
match HOST. */
|
match HOST. */
|
||||||
ocnt = 0;
|
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)
|
for (cookie = chains[i]; cookie; cookie = cookie->next)
|
||||||
{
|
{
|
||||||
int pg;
|
int pg;
|
||||||
@ -1111,6 +1114,7 @@ cookie_header (struct cookie_jar *jar, const char *host,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
result[pos++] = '\0';
|
result[pos++] = '\0';
|
||||||
|
xfree (outgoing);
|
||||||
assert (pos == result_size);
|
assert (pos == result_size);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ request_send (const struct request *req, int fd, FILE *warc_tmp)
|
|||||||
/* "\r\n\0" */
|
/* "\r\n\0" */
|
||||||
size += 3;
|
size += 3;
|
||||||
|
|
||||||
p = request_string = alloca_array (char, size);
|
p = request_string = xmalloc (size);
|
||||||
|
|
||||||
/* Generate the request. */
|
/* 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. */
|
/* Write a copy of the data to the WARC record. */
|
||||||
int warc_tmp_written = fwrite (request_string, 1, size - 1, warc_tmp);
|
int warc_tmp_written = fwrite (request_string, 1, size - 1, warc_tmp);
|
||||||
if (warc_tmp_written != size - 1)
|
if (warc_tmp_written != size - 1)
|
||||||
return -2;
|
write_error = -2;
|
||||||
}
|
}
|
||||||
|
xfree (request_string);
|
||||||
return write_error;
|
return write_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user