From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server-vie001.gnuweeb.org X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,URIBL_DBL_BLOCKED_OPENDNS, URIBL_ZEN_BLOCKED_OPENDNS autolearn=ham autolearn_force=no version=3.4.6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gnuweeb.org; s=new2025; t=1756391820; bh=YO71j2maw1PA/IdL/ZUvwSR6rEScmdOI88PMEkBOvzA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Transfer-Encoding:Message-ID:Date:From: Reply-To:Subject:To:Cc:In-Reply-To:References:Resent-Date: Resent-From:Resent-To:Resent-Cc:User-Agent:Content-Type: Content-Transfer-Encoding; b=wi2TzGxhIz5wcWl3SYGZyljZZgyA0m++uF00ZPGODAhpOY1ox6ams1soAgY6sx3o3 0xOvPZGEVGPgAAyyXbUPx4el6KrkDbFinjIAHS1QqYDjsXqZbL8iF6gMGgI1BkFCPp TA+feiSnpX5Lr5VDHG4KILV1hFIM1J/tJuzJTxI+YE/AZkC3RqZ7E96xL9Y7ik+A3p u8yWaOCZ9NG6mw+c2L48OyAY2ht/eEHgjXwr8a/dQs+nCCajrjBrhYBn9wBwiQDw02 77BfXBkxtaMSauJHen+FKi6OsD0YN9XYsL/yU8ScefpmvAAngZNKWNNbR0aMK7fhXb 3BlC2k7xAMHSw== Received: from zero (unknown [182.253.228.107]) by server-vie001.gnuweeb.org (Postfix) with ESMTPSA id 656733127F72; Thu, 28 Aug 2025 14:36:52 +0000 (UTC) From: Ahmad Gani To: Ammar Faizi Cc: Ahmad Gani , Alviro Iskandar Setiawan , GNU/Weeb Mailing List Subject: [PATCH gwproxy v6 05/11] dnsparser: Ignore CNAME if any Date: Thu, 28 Aug 2025 21:34:27 +0700 Message-ID: <20250828143444.540247-6-reyuki@gnuweeb.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250828143444.540247-1-reyuki@gnuweeb.org> References: <20250828143444.540247-1-reyuki@gnuweeb.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Previously the parser will abort the program if it detects a type other than A or AAAA record. and other minor changes Signed-off-by: Ahmad Gani --- src/gwproxy/dnsparser.c | 63 +++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/src/gwproxy/dnsparser.c b/src/gwproxy/dnsparser.c index 7b3a3c981ea7..cb2a090dfbb0 100644 --- a/src/gwproxy/dnsparser.c +++ b/src/gwproxy/dnsparser.c @@ -20,7 +20,7 @@ static ssize_t construct_qname(uint8_t *dst, size_t dst_len, const char *qname) return -ENAMETOOLONG; if (c == '.' || c == '\0') { - if (l < 1 || l > 255) + if (l < 1 || l > DOMAIN_LABEL_LIMIT) return -EINVAL; *lp = (uint8_t)l; @@ -51,14 +51,19 @@ static int calculate_question_len(uint8_t *in, size_t in_len) } if (tot_len >= (int)in_len) - return -ENAMETOOLONG; + return -ENOBUFS; advance_len = *p + 1; tot_len += advance_len; p += advance_len; } + if (tot_len > DOMAIN_NAME_LIMIT) + return -ENAMETOOLONG; + tot_len += 4; + if (tot_len >= (int)in_len) + return -ENOBUFS; return tot_len; } @@ -133,7 +138,8 @@ static int serialize_answ(uint16_t txid, uint8_t *in, size_t in_len, gwdns_answ_ } memcpy(&is_compressed, &in[idx], sizeof(is_compressed)); - is_compressed = DNS_IS_COMPRESSED(ntohs(is_compressed)); + is_compressed = ntohs(is_compressed); + is_compressed = DNS_IS_COMPRESSED(is_compressed); assert(is_compressed); idx += 2; // NAME if (idx >= in_len) { @@ -169,21 +175,33 @@ static int serialize_answ(uint16_t txid, uint8_t *in, size_t in_len, gwdns_answ_ memcpy(&rdlength, &in[idx], sizeof(rdlength)); rdlength = ntohs(rdlength); - if (item->rr_type != TYPE_AAAA && item->rr_type != TYPE_A) { - ret = -EINVAL; - free(item); - goto exit_free; - } - if (item->rr_type == TYPE_AAAA && rdlength != sizeof(struct in6_addr)) { - ret = -EINVAL; + switch (item->rr_type) { + case TYPE_AAAA: + if (rdlength != sizeof(struct in6_addr)) { + ret = -EINVAL; + free(item); + goto exit_free; + } + break; + case TYPE_A: + if (rdlength != sizeof(struct in_addr)) { + ret = -EINVAL; + free(item); + goto exit_free; + } + break; + case TYPE_CNAME: + idx += 2 + rdlength; free(item); - goto exit_free; - } - if (item->rr_type == TYPE_A && rdlength != sizeof(struct in_addr)) { + continue; + + default: ret = -EINVAL; free(item); goto exit_free; + break; } + item->rdlength = rdlength; idx += 2; if (idx >= in_len) { @@ -192,13 +210,6 @@ static int serialize_answ(uint16_t txid, uint8_t *in, size_t in_len, gwdns_answ_ goto exit_free; } - /* - * considering if condition above, - * maybe we don't need a malloc and just allocate fixed size - * for rdata? however if this parser want to be expanded for - * other dns operation (e.g OPCODE_IQUERY, etc), rdata maybe - * contain more than sizeof in6_addr. - */ ptr = malloc(rdlength); if (!ptr) { ret = -ENOMEM; @@ -216,10 +227,15 @@ static int serialize_answ(uint16_t txid, uint8_t *in, size_t in_len, gwdns_answ_ } item->rdata = ptr; - out->rr_answ[i] = item; + out->rr_answ[out->hdr.ancount] = item; out->hdr.ancount++; } + if (!out->hdr.ancount) { + free(out->rr_answ); + return -ENODATA; + } + return 0; exit_free: for (i = 0; i < out->hdr.ancount; i++) { @@ -258,10 +274,7 @@ int gwdns_parse_query(uint16_t txid, const char *service, if (r) return r; - if (!raw_answ.hdr.ancount) - goto exit_free; - - tail = NULL; + results = tail = NULL; for (i = 0; i < raw_answ.hdr.ancount; i++) { struct gwdns_addrinfo_node *new_node; gwdns_serialized_answ *answ; -- Ahmad Gani