mg_dns_parse_name() recursion protection

This commit is contained in:
cpq 2020-12-11 14:02:52 +00:00
parent 30d4a1ad0f
commit 85c5577955
3 changed files with 9 additions and 4 deletions

View File

@ -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,
char *to, size_t tolen, int depth) {
size_t i = 0, j = 0;
// if (depth > 5) return 0;
while (&s[off + i + 1] < e && s[off + i] > 0) {
size_t n = s[off + i];
if (n & 0xc0) {
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);
}
i++;

View File

@ -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,
char *to, size_t tolen, int depth) {
size_t i = 0, j = 0;
if (depth > 5) return 0;
while (&s[off + i + 1] < e && s[off + i] > 0) {
size_t n = s[off + i];
if (n & 0xc0) {
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);
}
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) {
struct mg_dns_header *h = (struct mg_dns_header *) buf;
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;
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;
// LOG(LL_INFO, ("QUE [%s]", name));
}

View File

@ -864,7 +864,10 @@ static void test_str(void) {
static void test_dns(void) {
struct mg_dns_message dm;
char *data = mg_file_read("data.txt");
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) {