}
static guint8 *
-decompress_label (guint8 *begin, guint16 *len)
+decompress_label (guint8 *begin, guint16 *len, guint16 max)
{
guint16 offset;
offset = ntohs ((*len) ^ DNS_COMPRESSION_BITS);
+ if (offset > max) {
+ return NULL;
+ }
*len = *(begin + offset);
return begin + offset;
}
/* This may be compressed, so we need to decompress it */
if (len1 & DNS_COMPRESSION_BITS) {
memcpy (&len1, p, sizeof (guint16));
- l1 = decompress_label (in, &len1);
+ l1 = decompress_label (in, &len1, len);
+ if (l1 == NULL) {
+ msg_info ("invalid DNS pointer");
+ return NULL;
+ }
decompressed ++;
l1 ++;
p += 2;
}
if (len2 & DNS_COMPRESSION_BITS) {
memcpy (&len2, p, sizeof (guint16));
- l2 = decompress_label (req->packet, &len2);
+ l2 = decompress_label (req->packet, &len2, len);
+ if (l2 == NULL) {
+ msg_info ("invalid DNS pointer");
+ return NULL;
+ }
decompressed ++;
l2 ++;
c += 2;
else if (llen & DNS_COMPRESSION_BITS) {
ptrs ++;
memcpy (&llen, p, sizeof (guint16));
- l = decompress_label (in, &llen);
+ l = decompress_label (in, &llen, length + (*pos - in));
+ if (l == NULL) {
+ msg_info ("invalid DNS pointer");
+ return FALSE;
+ }
if (offset < 0) {
offset = p - begin + 2;
}
}
else if (llen & DNS_COMPRESSION_BITS) {
memcpy (&llen, p, sizeof (guint16));
- l = decompress_label (in, &llen);
+ l = decompress_label (in, &llen, length + (*pos - in));
begin = p;
p = l + *l + 1;
namelen += *p;
/* Actually this copy memory, so using of inet_ntoa is valid */
lua_pushstring (cd->L, inet_ntoa (ina));
lua_rawseti (cd->L, -2, ++i);
+ cur = g_list_next (cur);
}
lua_pushnil (cd->L);
}
elt = cur->data;
lua_pushstring (cd->L, elt->ptr.name);
lua_rawseti (cd->L, -2, ++i);
+ cur = g_list_next (cur);
}
lua_pushnil (cd->L);
elt = cur->data;
lua_pushstring (cd->L, elt->txt.data);
lua_rawseti (cd->L, -2, ++i);
+ cur = g_list_next (cur);
}
lua_pushnil (cd->L);