Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 52 additions & 7 deletions modules/network/dns/moddnsparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,19 @@ static void *getQuestionByIndex(xsMachine *the, uint8_t index)
position += 12;
while (index--) {
while (true) {
Comment thread
phoddie marked this conversation as resolved.
Outdated
if (position >= packetEnd)
return NULL;
uint8_t tag = *position++;
if (0 == tag)
break;
if (0xC0 == (tag & 0xC0)) {
if (position >= packetEnd)
return NULL;
position += 1;
break;
}
if (position + tag > packetEnd)
return NULL;
position += tag;
}
position += 4;
Expand All @@ -75,6 +81,9 @@ static void *getAnswerByIndex(xsMachine *the, uint8_t index)
uint16_t answers = ((position[6] << 8) | position[7]) + ((position[8] << 8) | position[9]) + ((position[10] << 8) | position[11]); // including authority and additional records
position = getQuestionByIndex(the, 0xff);

if (NULL == position)
return NULL;

if ((0xff != index) && (index >= answers))
return NULL;

Expand All @@ -85,13 +94,19 @@ static void *getAnswerByIndex(xsMachine *the, uint8_t index)
uint16_t rdlength;

while (true) {
if (position >= packetEnd)
return NULL;
uint8_t tag = *position++;
if (0 == tag)
break;
if (0xC0 == (tag & 0xC0)) {
if (position >= packetEnd)
return NULL;
position += 1;
break;
}
if (position + tag > packetEnd)
return NULL;
position += tag;
}
position += 10;
Expand All @@ -107,37 +122,57 @@ static void *getAnswerByIndex(xsMachine *the, uint8_t index)
return position;
}

#define kDNSQnameMaxHops 128

static int parseQname(xsMachine *the, int offset)
{
uint8_t *packetEnd;
uint8_t *packetStart = getPacket(the, &packetEnd);
xsUnsignedValue packetLength = (xsUnsignedValue)(packetEnd - packetStart);
uint8_t *position;
int qnameEndPosition = 0;
int hops = 0;

xsVar(1) = xsNewArray(0);
position = offset + (uint8_t *)getPacket(the, NULL);;
position = offset + packetStart;
Comment thread
phoddie marked this conversation as resolved.
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)
qnameEndPosition = offset;
break;
}
if (0xC0 == (tag & 0xC0)) {
int ptr;
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);
ptr = ((tag << 8) | *position) & 0x3FFF;
if ((xsUnsignedValue)ptr >= packetLength)
xsUnknownError("bad name");
if (++hops > kDNSQnameMaxHops)
xsUnknownError("bad name");
offset = ptr;
position = offset + packetStart;
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 + packetStart;
Comment thread
phoddie marked this conversation as resolved.
}

return qnameEndPosition;
Expand Down Expand Up @@ -243,14 +278,24 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans
else
if (0x0010 == qtype) { // TXT
if (rdlength > 1) {
uint8_t *rdataEnd;
xsVar(1) = xsNewArray(0);
position = offset + (uint8_t *)getPacket(the, NULL);
rdataEnd = position + rdlength;
while (rdlength > 1) {
uint8_t tag;
uint16_t advance;

if (position >= rdataEnd)
break;
tag = *position++;
offset += tag + 1; //@@ bounds check range
rdlength -= tag + 1;
advance = (uint16_t)tag + 1;
if (advance > rdlength)
break;
if (position + tag > rdataEnd)
break;
offset += advance;
rdlength -= advance;
c_memcpy(tmp, position, tag);
xsmcSetStringBuffer(xsVar(2), tmp, tag);
xsCall1(xsVar(1), xsID_push, xsVar(2));
Expand Down