dns.c: improve input validation
[project/mdnsd.git] / dns.c
diff --git a/dns.c b/dns.c
index 86e5ea3aaa6c7f44cc4d52d4082b8ec9580046e0..c64f3b1be3d3e73fa4453a0158d850b958ce110e 100644 (file)
--- a/dns.c
+++ b/dns.c
@@ -222,6 +222,7 @@ scan_name(const uint8_t *buffer, int len)
                if (IS_COMPRESSED(l))
                        return offset + 2;
 
                if (IS_COMPRESSED(l))
                        return offset + 2;
 
+               if (l + 1 > len) return -1;
                len -= l + 1;
                offset += l + 1;
                buffer += l + 1;
                len -= l + 1;
                offset += l + 1;
                buffer += l + 1;
@@ -317,7 +318,7 @@ static int parse_answer(struct interface *iface, struct sockaddr *from,
        struct dns_answer *a;
        uint8_t *rdata;
 
        struct dns_answer *a;
        uint8_t *rdata;
 
-       if (!name) {
+       if (!name || rlen < 0) {
                fprintf(stderr, "dropping: bad question\n");
                return -1;
        }
                fprintf(stderr, "dropping: bad question\n");
                return -1;
        }
@@ -421,7 +422,7 @@ dns_handle_packet(struct interface *iface, struct sockaddr *from, uint16_t port,
                char *name = dns_consume_name(buffer, len, &b, &rlen);
                struct dns_question *q;
 
                char *name = dns_consume_name(buffer, len, &b, &rlen);
                struct dns_question *q;
 
-               if (!name) {
+               if (!name || rlen < 0) {
                        fprintf(stderr, "dropping: bad name\n");
                        return;
                }
                        fprintf(stderr, "dropping: bad name\n");
                        return;
                }