From 16ac79a8f720a917b0f787178905a8df56d4d557 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Fri, 1 Jul 2022 11:40:37 +1000
Subject: [PATCH] Check for overflow in $GENERATE computations

$GENERATE uses 'int' for its computations and some constructions
can overflow values that can be represented by an 'int' resulting
in undefined behaviour.  Detect these conditions and return a
range error.

(cherry picked from commit 5327b9708fd0e5d0d6c95183cca9eafb4a1cfe05)
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/16ac79a8f720a917b0f787178905a8df56d4d557
---
 .../checkzone/zones/bad-generate-range.db      | 18 ++++++++++++++++++
 lib/dns/master.c                               |  7 +++++++
 2 files changed, 25 insertions(+)
 create mode 100644 bin/tests/system/checkzone/zones/bad-generate-range.db

diff --git a/bin/tests/system/checkzone/zones/bad-generate-range.db b/bin/tests/system/checkzone/zones/bad-generate-range.db
new file mode 100644
index 0000000000..62a9e15684
--- /dev/null
+++ b/bin/tests/system/checkzone/zones/bad-generate-range.db
@@ -0,0 +1,18 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0.  If a copy of the MPL was not distributed with this
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 600
+@		SOA	ns hostmaster 2011012708 3600 1200 604800 1200
+		NS	ns
+ns		A	192.0.2.1
+
+; 2147483647 + 1 overflows what can be represented in an 'int'
+$GENERATE 1-1   host$	TXT foo${2147483647}
diff --git a/lib/dns/master.c b/lib/dns/master.c
index e1ba723104..e938b15a0e 100644
--- a/lib/dns/master.c
+++ b/lib/dns/master.c
@@ -735,6 +735,13 @@ genname(char *name, int it, char *buffer, size_t length) {
 					continue;
 				}
 			}
+			/*
+			 * 'it' is >= 0 so we don't need to check for
+			 * underflow.
+			 */
+			if ((it > 0 && delta > INT_MAX - it)) {
+				return (ISC_R_RANGE);
+			}
 			if (nibblemode) {
 				n = nibbles(numbuf, sizeof(numbuf), width,
 					    mode[0], it + delta);
-- 
2.23.0

