mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
mg_dns_parse_name() recursion protection
This commit is contained in:
parent
30d4a1ad0f
commit
85c5577955
@ -165,11 +165,12 @@ void mg_resolve_cancel(struct mg_mgr *mgr, struct mg_connection *c) {
|
|||||||
static size_t mg_dns_parse_name(const uint8_t *s, const uint8_t *e, size_t off,
|
static size_t mg_dns_parse_name(const uint8_t *s, const uint8_t *e, size_t off,
|
||||||
char *to, size_t tolen, int depth) {
|
char *to, size_t tolen, int depth) {
|
||||||
size_t i = 0, j = 0;
|
size_t i = 0, j = 0;
|
||||||
|
// if (depth > 5) return 0;
|
||||||
while (&s[off + i + 1] < e && s[off + i] > 0) {
|
while (&s[off + i + 1] < e && s[off + i] > 0) {
|
||||||
size_t n = s[off + i];
|
size_t n = s[off + i];
|
||||||
if (n & 0xc0) {
|
if (n & 0xc0) {
|
||||||
size_t ptr = (((n & 0x3f) << 8) | s[off + i + 1]) - 12; // 12 is hdr len
|
size_t ptr = (((n & 0x3f) << 8) | s[off + i + 1]) - 12; // 12 is hdr len
|
||||||
if (&s[ptr + 1] < e && (s[ptr] & 0xc0) == 0 && depth < 5) {
|
if (&s[ptr + 1] < e && (s[ptr] & 0xc0) == 0) {
|
||||||
j = mg_dns_parse_name(s, e, ptr, to, tolen, depth + 1);
|
j = mg_dns_parse_name(s, e, ptr, to, tolen, depth + 1);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -39,11 +39,12 @@ void mg_resolve_cancel(struct mg_mgr *mgr, struct mg_connection *c) {
|
|||||||
static size_t mg_dns_parse_name(const uint8_t *s, const uint8_t *e, size_t off,
|
static size_t mg_dns_parse_name(const uint8_t *s, const uint8_t *e, size_t off,
|
||||||
char *to, size_t tolen, int depth) {
|
char *to, size_t tolen, int depth) {
|
||||||
size_t i = 0, j = 0;
|
size_t i = 0, j = 0;
|
||||||
|
if (depth > 5) return 0;
|
||||||
while (&s[off + i + 1] < e && s[off + i] > 0) {
|
while (&s[off + i + 1] < e && s[off + i] > 0) {
|
||||||
size_t n = s[off + i];
|
size_t n = s[off + i];
|
||||||
if (n & 0xc0) {
|
if (n & 0xc0) {
|
||||||
size_t ptr = (((n & 0x3f) << 8) | s[off + i + 1]) - 12; // 12 is hdr len
|
size_t ptr = (((n & 0x3f) << 8) | s[off + i + 1]) - 12; // 12 is hdr len
|
||||||
if (&s[ptr + 1] < e && (s[ptr] & 0xc0) == 0 && depth < 5) {
|
if (&s[ptr + 1] < e && (s[ptr] & 0xc0) == 0) {
|
||||||
j = mg_dns_parse_name(s, e, ptr, to, tolen, depth + 1);
|
j = mg_dns_parse_name(s, e, ptr, to, tolen, depth + 1);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@ -67,9 +68,9 @@ static size_t mg_dns_parse_name(const uint8_t *s, const uint8_t *e, size_t off,
|
|||||||
int mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
|
int mg_dns_parse(const uint8_t *buf, size_t len, struct mg_dns_message *dm) {
|
||||||
struct mg_dns_header *h = (struct mg_dns_header *) buf;
|
struct mg_dns_header *h = (struct mg_dns_header *) buf;
|
||||||
const uint8_t *s = buf + sizeof(*h), *e = &buf[len];
|
const uint8_t *s = buf + sizeof(*h), *e = &buf[len];
|
||||||
size_t i, j, n, ok = 0;
|
size_t i, j = 0, n, ok = 0;
|
||||||
if (len < sizeof(*h)) return ok;
|
if (len < sizeof(*h)) return ok;
|
||||||
for (i = j = 0; i < mg_ntohs(h->num_questions); i++) {
|
for (i = 0; i < mg_ntohs(h->num_questions); i++) {
|
||||||
j += mg_dns_parse_name(s, e, j, dm->name, sizeof(dm->name), 0) + 5;
|
j += mg_dns_parse_name(s, e, j, dm->name, sizeof(dm->name), 0) + 5;
|
||||||
// LOG(LL_INFO, ("QUE [%s]", name));
|
// LOG(LL_INFO, ("QUE [%s]", name));
|
||||||
}
|
}
|
||||||
|
@ -864,7 +864,10 @@ static void test_str(void) {
|
|||||||
|
|
||||||
static void test_dns(void) {
|
static void test_dns(void) {
|
||||||
struct mg_dns_message dm;
|
struct mg_dns_message dm;
|
||||||
|
char *data = mg_file_read("data.txt");
|
||||||
ASSERT(mg_dns_parse(NULL, 0, &dm) == 0);
|
ASSERT(mg_dns_parse(NULL, 0, &dm) == 0);
|
||||||
|
ASSERT(mg_dns_parse((uint8_t *) data, strlen(data), &dm) == 0);
|
||||||
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_util(void) {
|
static void test_util(void) {
|
||||||
|
Loading…
Reference in New Issue
Block a user