From: Vsevolod Stakhov Date: Mon, 10 Nov 2025 09:21:36 +0000 (+0000) Subject: [Fix] Preserve req->pos during reply validation to prevent packet truncation on retra... X-Git-Tag: 3.14.0~4^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1833877202e35b65600efcf159732f8bdeaefce9;p=thirdparty%2Frspamd.git [Fix] Preserve req->pos during reply validation to prevent packet truncation on retransmit The rdns_request_reply_cmp function modifies req->pos as a side effect during reply validation. This caused packet truncation on retransmits because req->pos (which tracks the full packet length) was overwritten with the end position of the question section. On timeout/retry, rdns_send_request would use the corrupted req->pos value, resulting in truncated packets missing the OPT additional section. This made resolvers like Knot and PowerDNS unable to parse retransmitted packets. Fix by saving and restoring req->pos around the reply comparison logic. --- diff --git a/contrib/librdns/resolver.c b/contrib/librdns/resolver.c index 117c85e15d..0613a6b4e5 100644 --- a/contrib/librdns/resolver.c +++ b/contrib/librdns/resolver.c @@ -220,17 +220,20 @@ rdns_parse_reply(uint8_t *in, int r, struct rdns_request *req, * Now we have request and query data is now at the end of header, so compare * request QR section and reply QR section */ + unsigned int saved_pos = req->pos; req->pos = sizeof(struct dns_header); pos = in + sizeof(struct dns_header); t = r - sizeof(struct dns_header); for (i = 0; i < (int) qdcount; i++) { if ((npos = rdns_request_reply_cmp(req, pos, t)) == NULL) { rdns_info("DNS request with id %d is for different query, ignoring", (int) req->id); + req->pos = saved_pos; return false; } t -= npos - pos; pos = npos; } + req->pos = saved_pos; /* * Now pos is in answer section, so we should extract data and form reply */