Skip to content

Commit

Permalink
resolved: clear the AD bit for bypass packets
Browse files Browse the repository at this point in the history
When the bypass logic is invoked, such as for queries to the stub with
the DO bit set, be certain to clear the AD bit in the reply before
forwarding it if the answer is not known to be authentic.

(cherry picked from commit 13e15dae9f0b4566d3ea2ed058a5dd44751216da)
(cherry picked from commit 3a2be652282db2d55d5e28546e6c9a594fb8c43e)
(cherry picked from commit 6c243bb)
  • Loading branch information
rpigott authored and bluca committed Sep 11, 2024
1 parent 0b6faf9 commit edec5cc
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/resolve/resolved-dns-packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ static inline uint8_t* DNS_PACKET_DATA(const DnsPacket *p) {
#define DNS_PACKET_AD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 5) & 1)
#define DNS_PACKET_CD(p) ((be16toh(DNS_PACKET_HEADER(p)->flags) >> 4) & 1)

#define DNS_PACKET_FLAG_AD (UINT16_C(1) << 5)
#define DNS_PACKET_FLAG_TC (UINT16_C(1) << 9)

static inline uint16_t DNS_PACKET_RCODE(DnsPacket *p) {
Expand Down
10 changes: 8 additions & 2 deletions src/resolve/resolved-dns-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,8 @@ static int dns_stub_send_failure(
static int dns_stub_patch_bypass_reply_packet(
DnsPacket **ret, /* Where to place the patched packet */
DnsPacket *original, /* The packet to patch */
DnsPacket *request) { /* The packet the patched packet shall look like a reply to */
DnsPacket *request, /* The packet the patched packet shall look like a reply to */
bool authenticated) {
_cleanup_(dns_packet_unrefp) DnsPacket *c = NULL;
int r;

Expand Down Expand Up @@ -725,6 +726,10 @@ static int dns_stub_patch_bypass_reply_packet(
DNS_PACKET_HEADER(c)->flags = htobe16(be16toh(DNS_PACKET_HEADER(c)->flags) | DNS_PACKET_FLAG_TC);
}

/* Ensure we don't pass along an untrusted ad flag for bypass packets */
if (!authenticated)
DNS_PACKET_HEADER(c)->flags = htobe16(be16toh(DNS_PACKET_HEADER(c)->flags) & ~DNS_PACKET_FLAG_AD);

*ret = TAKE_PTR(c);
return 0;
}
Expand All @@ -745,7 +750,8 @@ static void dns_stub_query_complete(DnsQuery *query) {
q->answer_full_packet->protocol == DNS_PROTOCOL_DNS) {
_cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;

r = dns_stub_patch_bypass_reply_packet(&reply, q->answer_full_packet, q->request_packet);
r = dns_stub_patch_bypass_reply_packet(&reply, q->answer_full_packet, q->request_packet,
FLAGS_SET(q->answer_query_flags, SD_RESOLVED_AUTHENTICATED));
if (r < 0)
log_debug_errno(r, "Failed to patch bypass reply packet: %m");
else
Expand Down

0 comments on commit edec5cc

Please sign in to comment.