From 054dc48a1f21dc249df613c89658accaf9d21986 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Sat, 22 Aug 2020 01:52:09 +1000
Subject: [PATCH] Only read dns_master_indent and dns_master_indentstr in named

The old code was not thread safe w.r.t. to the use of these variable.
We now only set them at the start of execution and copy them to
the message structure so they can be safely updated.  This is the
minimal change to make them thread safe.
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/054dc48a1f21dc249df613c89658accaf9d21986
---
 lib/dns/include/dns/message.h |  2 ++
 lib/dns/include/dns/types.h   |  5 +++++
 lib/dns/message.c             | 30 ++++++++++++++++--------------
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
index 0072d5a8f2..d567fae63b 100644
--- a/lib/dns/include/dns/message.h
+++ b/lib/dns/include/dns/message.h
@@ -263,6 +263,8 @@ struct dns_message {
 
 	dns_rdatasetorderfunc_t		order;
 	const void *			order_arg;
+
+	dns_indent_t			indent;
 };
 
 struct dns_ednsopt {
diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h
index 567e8a879e..a497c04bab 100644
--- a/lib/dns/include/dns/types.h
+++ b/lib/dns/include/dns/types.h
@@ -385,6 +385,11 @@ typedef enum {
 	dns_stale_answer_conf
 } dns_stale_answer_t;
 
+typedef struct {
+	const char *string;
+	size_t      count;
+} dns_indent_t;
+
 /*
  * Functions.
  */
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 9dafd69f11..6a6151952c 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -454,6 +454,8 @@ msginit(dns_message_t *m) {
 	m->tkey = 0;
 	m->rdclass_set = 0;
 	m->querytsig = NULL;
+	m->indent.string = dns_master_indentstr;
+	m->indent.count = dns_master_indent;
 }
 
 static inline void
@@ -3298,8 +3300,8 @@ dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
 		if ((__flags & DNS_STYLEFLAG_INDENT) == 0ULL && \
 		    (__flags & DNS_STYLEFLAG_YAML) == 0ULL) \
 			break; \
-		for (__i = 0; __i < dns_master_indent; __i++) { \
-			ADD_STRING(target, dns_master_indentstr); \
+		for (__i = 0; __i < msg->indent.count; __i++) { \
+			ADD_STRING(target, msg->indent.string); \
 		} \
 	} while (0)
 
@@ -3319,7 +3321,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
 	REQUIRE(target != NULL);
 	REQUIRE(VALID_SECTION(section));
 
-	saveindent = dns_master_indent;
+	saveindent = msg->indent.count;
 	sflags = dns_master_styleflags(style);
 	if (ISC_LIST_EMPTY(msg->sections[section]))
 		goto cleanup;
@@ -3349,7 +3351,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
 		goto cleanup;
 	}
 	if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
-		dns_master_indent++;
+		msg->indent.count++;
 	}
 	do {
 		name = NULL;
@@ -3389,7 +3391,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
 		result = dns_message_nextname(msg, section);
 	} while (result == ISC_R_SUCCESS);
 	if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
-		dns_master_indent--;
+		msg->indent.count--;
 	}
 	if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
 	    (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0 &&
@@ -3402,7 +3404,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
 		result = ISC_R_SUCCESS;
 
  cleanup:
-	dns_master_indent = saveindent;
+	msg->indent.count = saveindent;
 	return (result);
 }
 
@@ -3519,7 +3521,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
 	isc_buffer_t optbuf;
 	uint16_t optcode, optlen;
 	unsigned char *optdata;
-	unsigned int saveindent = dns_master_indent;
+	unsigned int saveindent = msg->indent.count;
 	unsigned int optindent;
 
 	REQUIRE(DNS_MESSAGE_VALID(msg));
@@ -3535,11 +3537,11 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
 
 		INDENT(style);
 		ADD_STRING(target, "OPT_PSEUDOSECTION:\n");
-		dns_master_indent++;
+		msg->indent.count++;
 
 		INDENT(style);
 		ADD_STRING(target, "EDNS:\n");
-		dns_master_indent++;
+		msg->indent.count++;
 
 		INDENT(style);
 		ADD_STRING(target, "version: ");
@@ -3583,10 +3585,10 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
 
 		isc_buffer_init(&optbuf, rdata.data, rdata.length);
 		isc_buffer_add(&optbuf, rdata.length);
-		optindent = dns_master_indent;
+		optindent = msg->indent.count;
 		while (isc_buffer_remaininglength(&optbuf) != 0) {
 			bool extra_text = false;
-			dns_master_indent = optindent;
+			msg->indent.count = optindent;
 			INSIST(isc_buffer_remaininglength(&optbuf) >= 4U);
 			optcode = isc_buffer_getuint16(&optbuf);
 			optlen = isc_buffer_getuint16(&optbuf);
@@ -3672,7 +3674,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
 				if (optlen >= 2U) {
 					uint16_t ede;
 					ADD_STRING(target, ":\n");
-					dns_master_indent++;
+					msg->indent.count++;
 					INDENT(style);
 					ADD_STRING(target, "INFO-CODE:");
 					ede = isc_buffer_getuint16(&optbuf);
@@ -3816,7 +3818,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
 			}
 			ADD_STRING(target, "\n");
 		}
-		dns_master_indent = optindent;
+		msg->indent.count = optindent;
 		result = ISC_R_SUCCESS;
 		goto cleanup;
 	case DNS_PSEUDOSECTION_TSIG:
@@ -3848,7 +3850,7 @@ dns_message_pseudosectiontoyaml(dns_message_t *msg,
 	result = ISC_R_UNEXPECTED;
 
  cleanup:
-	dns_master_indent = saveindent;
+	msg->indent.count = saveindent;
 	return (result);
 }
 
-- 
2.23.0

