mirror of
https://github.com/nodejs/http-parser.git
synced 2025-10-20 13:44:52 +08:00
src: fix out-of-bounds read through strtoul
`strtoul` will attempt to lookup the next digit up until it will stumble upon an invalid one. However, for an unterminated string as an input value, this results in out-of-bounds read. Remove `strtoul` call, and replace it with simple loop. Fix: #408 PR-URL: https://github.com/nodejs/http-parser/pull/409 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
@@ -2367,12 +2366,27 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
|
||||
}
|
||||
|
||||
if (u->field_set & (1 << UF_PORT)) {
|
||||
/* Don't bother with endp; we've already validated the string */
|
||||
unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
|
||||
uint16_t off;
|
||||
uint16_t len;
|
||||
const char* p;
|
||||
const char* end;
|
||||
unsigned long v;
|
||||
|
||||
/* Ports have a max value of 2^16 */
|
||||
if (v > 0xffff) {
|
||||
return 1;
|
||||
off = u->field_data[UF_PORT].off;
|
||||
len = u->field_data[UF_PORT].len;
|
||||
end = buf + off + len;
|
||||
|
||||
/* NOTE: The characters are already validated and are in the [0-9] range */
|
||||
assert(off + len <= buflen && "Port number overflow");
|
||||
v = 0;
|
||||
for (p = buf + off; p < end; p++) {
|
||||
v *= 10;
|
||||
v += *p - '0';
|
||||
|
||||
/* Ports have a max value of 2^16 */
|
||||
if (v > 0xffff) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
u->port = (uint16_t) v;
|
||||
|
25
test.c
25
test.c
@@ -3664,6 +3664,30 @@ test_header_cr_no_lf_error (int req)
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
test_no_overflow_parse_url (void)
|
||||
{
|
||||
int rv;
|
||||
struct http_parser_url u;
|
||||
|
||||
http_parser_url_init(&u);
|
||||
rv = http_parser_parse_url("http://example.com:8001", 22, 0, &u);
|
||||
|
||||
if (rv != 0) {
|
||||
fprintf(stderr,
|
||||
"\n*** test_no_overflow_parse_url invalid return value=%d\n",
|
||||
rv);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (u.port != 800) {
|
||||
fprintf(stderr,
|
||||
"\n*** test_no_overflow_parse_url invalid port number=%d\n",
|
||||
u.port);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_header_overflow_error (int req)
|
||||
{
|
||||
@@ -4099,6 +4123,7 @@ main (void)
|
||||
test_header_nread_value();
|
||||
|
||||
//// OVERFLOW CONDITIONS
|
||||
test_no_overflow_parse_url();
|
||||
|
||||
test_header_overflow_error(HTTP_REQUEST);
|
||||
test_no_overflow_long_body(HTTP_REQUEST, 1000);
|
||||
|
Reference in New Issue
Block a user