]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: correct parsing of OPT extended RCODEs 33523/head
authorJames Coglan <james@neighbourhood.ie>
Fri, 28 Jun 2024 12:58:22 +0000 (13:58 +0100)
committerJames Coglan <james@neighbourhood.ie>
Fri, 28 Jun 2024 13:09:46 +0000 (14:09 +0100)
The DNS_PACKET_RCODE() function works out the full RCODE by taking the
first octet from the OPT record TTL field and bitwise-OR-ing this with
the basic RCODE from the packet header. This results in RCODE values
being lower than they should be.

For example, if the first TTL octet is 0x7a and the basic RCODE is 3,
this function currently returns `0x7a | 3` = 123, rather than 0x7a3 =
1955.

The first TTL octet is supposed to form the upper 8 bits of a 12-bit
value, whereas the current implementation constraints the value to 8
bits and results in mis-interpreted RCODEs.

This fixes things by shifting the TTL 20 places instead of 24 and
masking off the low nibble that comes from the upper bits of the version
octet.

Note that dns_packet_append_opt() correctly converts the input RCODE
into the high octet of the OPT TTL field; this problem only affects
parsing of incoming packets.

src/resolve/resolved-dns-packet.h

index 8f5a08e3579890cc38e7d073520efcc1088c7ebb..a2e25231df8b3c3f1f578b3a581cc26580dc3679 100644 (file)
@@ -117,7 +117,7 @@ static inline uint16_t DNS_PACKET_RCODE(DnsPacket *p) {
         uint16_t rcode;
 
         if (p->opt)
-                rcode = (uint16_t) (p->opt->ttl >> 24);
+                rcode = (uint16_t) ((p->opt->ttl >> 20) & 0xFF0);
         else
                 rcode = 0;