From 2a9300a3bcd2c2cb5027e3435c53d2b8d94d72fd Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Tue, 10 Jan 2023 17:15:09 +1100
Subject: [PATCH] Don't perform arithmetic on NULL pointers

When node is NULL when calling getparent() et al. they return NULL
but performing arithmetic on the NULL pointer is undefined.  Check
if 'node' or 'header' is NULL and skip the adjustment.

Conflict: The content of the patch has not been changed, the patch context does not match, it is suitable for the patch
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/2a9300a3bcd2c2cb5027e3435c53d2b8d94d72fd

---
 lib/dns/rbt.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c
index 7f2c2d2..3fa2999 100644
--- a/lib/dns/rbt.c
+++ b/lib/dns/rbt.c
@@ -166,6 +166,10 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
 		dns_rbtdatawriter_t datawriter, void *writer_arg,
 		uintptr_t *where, uint64_t *crc);
 
+#define ADJUST_ADDRESS(address, relative, header)        \
+	if (address != NULL && header != NULL) {         \
+		address += relative * (uintptr_t)header; \
+	}
 /*
  * The following functions allow you to get the actual address of a pointer
  * without having to use an if statement to check to see if that address is
@@ -174,7 +178,8 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
 static inline dns_rbtnode_t *
 getparent(dns_rbtnode_t *node, file_header_t *header) {
 	char *adjusted_address = (char *)(node->parent);
-	adjusted_address += node->parent_is_relative * (uintptr_t)header;
+
+	ADJUST_ADDRESS(adjusted_address, node->parent_is_relative, header);
 
 	return ((dns_rbtnode_t *)adjusted_address);
 }
@@ -182,7 +187,8 @@ getparent(dns_rbtnode_t *node, file_header_t *header) {
 static inline dns_rbtnode_t *
 getleft(dns_rbtnode_t *node, file_header_t *header) {
 	char *adjusted_address = (char *)(node->left);
-	adjusted_address += node->left_is_relative * (uintptr_t)header;
+
+	ADJUST_ADDRESS(adjusted_address, node->left_is_relative, header);
 
 	return ((dns_rbtnode_t *)adjusted_address);
 }
@@ -190,7 +196,8 @@ getleft(dns_rbtnode_t *node, file_header_t *header) {
 static inline dns_rbtnode_t *
 getright(dns_rbtnode_t *node, file_header_t *header) {
 	char *adjusted_address = (char *)(node->right);
-	adjusted_address += node->right_is_relative * (uintptr_t)header;
+
+	ADJUST_ADDRESS(adjusted_address, node->right_is_relative, header);
 
 	return ((dns_rbtnode_t *)adjusted_address);
 }
@@ -198,7 +205,8 @@ getright(dns_rbtnode_t *node, file_header_t *header) {
 static inline dns_rbtnode_t *
 getdown(dns_rbtnode_t *node, file_header_t *header) {
 	char *adjusted_address = (char *)(node->down);
-	adjusted_address += node->down_is_relative * (uintptr_t)header;
+
+	ADJUST_ADDRESS(adjusted_address, node->down_is_relative, header);
 
 	return ((dns_rbtnode_t *)adjusted_address);
 }
@@ -206,7 +214,8 @@ getdown(dns_rbtnode_t *node, file_header_t *header) {
 static inline dns_rbtnode_t *
 getdata(dns_rbtnode_t *node, file_header_t *header) {
 	char *adjusted_address = (char *)(node->data);
-	adjusted_address += node->data_is_relative * (uintptr_t)header;
+
+	ADJUST_ADDRESS(adjusted_address, node->data_is_relative, header);
 
 	return ((dns_rbtnode_t *)adjusted_address);
 }
-- 
2.33.0

