diff --git a/modules/network/dns/moddnsparser.c b/modules/network/dns/moddnsparser.c index bd88eea69..6fdf18992 100644 --- a/modules/network/dns/moddnsparser.c +++ b/modules/network/dns/moddnsparser.c @@ -51,7 +51,10 @@ static void *getQuestionByIndex(xsMachine *the, uint8_t index) position += 12; while (index--) { while (true) { - uint8_t tag = *position++; + uint8_t tag; + if (position >= packetEnd) + return NULL; + tag = *position++; if (0 == tag) break; if (0xC0 == (tag & 0xC0)) { @@ -85,7 +88,10 @@ static void *getAnswerByIndex(xsMachine *the, uint8_t index) uint16_t rdlength; while (true) { - uint8_t tag = *position++; + uint8_t tag; + if (position >= packetEnd) + return NULL; + tag = *position++; if (0 == tag) break; if (0xC0 == (tag & 0xC0)) { @@ -109,14 +115,18 @@ static void *getAnswerByIndex(xsMachine *the, uint8_t index) static int parseQname(xsMachine *the, int offset) { - uint8_t *position; + uint8_t *position, *packetEnd; + uint8_t *packet = getPacket(the, &packetEnd); int qnameEndPosition = 0; xsVar(1) = xsNewArray(0); - position = offset + (uint8_t *)getPacket(the, NULL);; + position = offset + packet; while (true) { char tmp[64]; - uint8_t tag = *position++; + uint8_t tag; + if (position >= packetEnd) + xsUnknownError("bad name"); + tag = *position++; offset += 1; if (0 == tag) { if (0 == qnameEndPosition) @@ -124,20 +134,26 @@ static int parseQname(xsMachine *the, int offset) break; } if (0xC0 == (tag & 0xC0)) { + if (position >= packetEnd) + xsUnknownError("bad name"); if (0 == qnameEndPosition) qnameEndPosition = offset + 1; - offset = ((tag << 8) | *position) & 0x3FFF; //@@ range check - position = offset + (uint8_t *)getPacket(the, NULL); + offset = ((tag << 8) | *position) & 0x3FFF; + if (offset >= packetEnd - packet) + xsUnknownError("bad name"); + position = offset + packet; continue; } if (tag > 63) xsUnknownError("bad name"); + if (position + tag > packetEnd) + xsUnknownError("bad name"); c_memcpy(tmp, position, tag); xsmcSetStringBuffer(xsVar(2), tmp, tag); xsCall1(xsVar(1), xsID_push, xsVar(2)); offset += tag; - position = offset + (uint8_t *)getPacket(the, NULL); + position = offset + packet; } return qnameEndPosition; @@ -148,13 +164,15 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans int offset; uint16_t qtype, qclass; char tmp[256]; + uint8_t *packet, *packetEnd; if (NULL == position) { xsmcSetNull(xsResult); return; } - offset = position - (uint8_t *)getPacket(the, NULL); + packet = getPacket(the, &packetEnd); + offset = position - packet; xsmcVars(4); @@ -163,8 +181,10 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans offset = parseQname(the, offset); xsmcSet(xsVar(0), xsID_qname, xsVar(1)); - position = offset + (uint8_t *)getPacket(the, NULL); + position = offset + packet; + if (position + 4 > packetEnd) + xsUnknownError("bad name"); qtype = (position[0] << 8) | position[1]; qclass = (position[2] << 8) | position[3]; position += 4; @@ -174,16 +194,22 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans uint32_t ttl; uint16_t rdlength; + if (position + 6 > packetEnd) + xsUnknownError("bad name"); ttl = (position[0] << 24) | (position[1] << 16) | (position[2] << 8) | position[3]; rdlength = (position[4] << 8) | position[5]; position += 6; offset += 6; + if (position + rdlength > packetEnd) + xsUnknownError("bad name"); if (rdlength) { if (0x0001 == qtype) { // A uint8_t ip[4]; char *out; + if (position + 4 > packetEnd) + xsUnknownError("bad name"); c_memcpy(ip, position, 4); xsVar(1) = xsStringBuffer(NULL, 4 * 5); out = xsmcToString(xsVar(1)); @@ -223,9 +249,12 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans else #endif if (0x0021 == qtype) { // SRV - uint16_t priority = (position[0] << 8) | position[1]; - uint16_t weight = (position[2] << 8) | position[3]; - uint16_t port = (position[4] << 8) | position[5]; + uint16_t priority, weight, port; + if (position + 6 > packetEnd) + xsUnknownError("bad name"); + priority = (position[0] << 8) | position[1]; + weight = (position[2] << 8) | position[3]; + port = (position[4] << 8) | position[5]; offset += 6; xsVar(3) = xsNewObject(); @@ -246,10 +275,11 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans xsVar(1) = xsNewArray(0); position = offset + (uint8_t *)getPacket(the, NULL); while (rdlength > 1) { - uint8_t tag; + uint8_t tag = *position++; - tag = *position++; - offset += tag + 1; //@@ bounds check range + if (tag + 1 > rdlength) + break; + offset += tag + 1; rdlength -= tag + 1; c_memcpy(tmp, position, tag); xsmcSetStringBuffer(xsVar(2), tmp, tag);