From b1146514451d57dff844dbfa2c6767d79acb8b7f Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Tue, 25 Aug 2020 22:59:35 +1000
Subject: [PATCH] Cast the original rcode to (dns_ttl_t) when setting extended
 rcode

Shifting (signed) integer left could trigger undefined behaviour when
the shifted value would overflow into the sign bit (e.g. 2048).

The issue was found when using AFL++ and UBSAN:

    message.c:2274:33: runtime error: left shift of 2048 by 20 places cannot be represented in type 'int'
    SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior message.c:2274:33 in

(cherry picked from commit a347641782dfb47aa45e6e8ffc9e0c6db4c07deb)
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/b1146514451d57dff844dbfa2c6767d79acb8b7f
---
 lib/dns/message.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/dns/message.c b/lib/dns/message.c
index 7c813a5cf6..9dafd69f11 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -2318,10 +2318,11 @@ dns_message_renderend(dns_message_t *msg) {
 		dns_message_renderrelease(msg, msg->opt_reserved);
 		msg->opt_reserved = 0;
 		/*
-		 * Set the extended rcode.
+		 * Set the extended rcode.  Cast msg->rcode to dns_ttl_t
+		 * so that we do a unsigned shift.
 		 */
 		msg->opt->ttl &= ~DNS_MESSAGE_EDNSRCODE_MASK;
-		msg->opt->ttl |= ((msg->rcode << 20) &
+		msg->opt->ttl |= (((dns_ttl_t)(msg->rcode) << 20) &
 				  DNS_MESSAGE_EDNSRCODE_MASK);
 		/*
 		 * Render.
-- 
2.23.0

