summaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/bind/bind/CVE-2023-3341.patch
blob: be479cb00e3a9e97343f6475ab8a54d791622727 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
From c4fac5ca98efd02fbaef43601627c7a3a09f5a71 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Tue, 20 Jun 2023 15:21:36 +1000
Subject: [PATCH] Limit isccc_cc_fromwire recursion depth

Named and rndc do not need a lot of recursion so the depth is
set to 10.

Taken from BIND 9.16.44 change.

Upstream-Status: Backport [https://gitlab.isc.org/isc-projects/bind9/-/commit/c4fac5ca98efd02fbaef43601627c7a3a09f5a71]
CVE: CVE-2023-3341
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
 lib/isccc/cc.c                   | 38 +++++++++++++++++++++++---------
 lib/isccc/include/isccc/result.h |  4 +++-
 lib/isccc/result.c               |  4 +++-
 3 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c
index e012685..8eac3d6 100644
--- a/lib/isccc/cc.c
+++ b/lib/isccc/cc.c
@@ -53,6 +53,10 @@
 
 #define MAX_TAGS		256
 #define DUP_LIFETIME		900
+#ifndef ISCCC_MAXDEPTH
+#define ISCCC_MAXDEPTH \
+	10 /* Big enough for rndc which just sends a string each way. */
+#endif
 
 typedef isccc_sexpr_t *sexpr_ptr;
 
@@ -561,19 +565,25 @@ verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length,
 
 static isc_result_t
 table_fromwire(isccc_region_t *source, isccc_region_t *secret,
-	       uint32_t algorithm, isccc_sexpr_t **alistp);
+	       uint32_t algorithm, unsigned int depth, isccc_sexpr_t **alistp);
 
 static isc_result_t
-list_fromwire(isccc_region_t *source, isccc_sexpr_t **listp);
+list_fromwire(isccc_region_t *source, unsigned int depth,
+	      isccc_sexpr_t **listp);
 
 static isc_result_t
-value_fromwire(isccc_region_t *source, isccc_sexpr_t **valuep) {
+value_fromwire(isccc_region_t *source, unsigned int depth,
+	       isccc_sexpr_t **valuep) {
 	unsigned int msgtype;
 	uint32_t len;
 	isccc_sexpr_t *value;
 	isccc_region_t active;
 	isc_result_t result;
 
+	if (depth > ISCCC_MAXDEPTH) {
+		return (ISCCC_R_MAXDEPTH);
+	}
+
 	if (REGION_SIZE(*source) < 1 + 4)
 		return (ISC_R_UNEXPECTEDEND);
 	GET8(msgtype, source->rstart);
@@ -591,9 +601,9 @@ value_fromwire(isccc_region_t *source, isccc_sexpr_t **valuep) {
 		} else
 			result = ISC_R_NOMEMORY;
 	} else if (msgtype == ISCCC_CCMSGTYPE_TABLE)
-		result = table_fromwire(&active, NULL, 0, valuep);
+		result = table_fromwire(&active, NULL, 0, depth + 1, valuep);
 	else if (msgtype == ISCCC_CCMSGTYPE_LIST)
-		result = list_fromwire(&active, valuep);
+		result = list_fromwire(&active, depth + 1, valuep);
 	else
 		result = ISCCC_R_SYNTAX;
 
@@ -602,7 +612,7 @@ value_fromwire(isccc_region_t *source, isccc_sexpr_t **valuep) {
 
 static isc_result_t
 table_fromwire(isccc_region_t *source, isccc_region_t *secret,
-	       uint32_t algorithm, isccc_sexpr_t **alistp)
+	       uint32_t algorithm, unsigned int depth, isccc_sexpr_t **alistp)
 {
 	char key[256];
 	uint32_t len;
@@ -613,6 +623,10 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret,
 
 	REQUIRE(alistp != NULL && *alistp == NULL);
 
+	if (depth > ISCCC_MAXDEPTH) {
+		return (ISCCC_R_MAXDEPTH);
+	}
+
 	checksum_rstart = NULL;
 	first_tag = true;
 	alist = isccc_alist_create();
@@ -628,7 +642,7 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret,
 		GET_MEM(key, len, source->rstart);
 		key[len] = '\0';	/* Ensure NUL termination. */
 		value = NULL;
-		result = value_fromwire(source, &value);
+		result = value_fromwire(source, depth + 1, &value);
 		if (result != ISC_R_SUCCESS)
 			goto bad;
 		if (isccc_alist_define(alist, key, value) == NULL) {
@@ -661,14 +675,18 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret,
 }
 
 static isc_result_t
-list_fromwire(isccc_region_t *source, isccc_sexpr_t **listp) {
+list_fromwire(isccc_region_t *source, unsigned int depth, isccc_sexpr_t **listp) {
 	isccc_sexpr_t *list, *value;
 	isc_result_t result;
 
+	if (depth > ISCCC_MAXDEPTH) {
+		return (ISCCC_R_MAXDEPTH);
+	}
+
 	list = NULL;
 	while (!REGION_EMPTY(*source)) {
 		value = NULL;
-		result = value_fromwire(source, &value);
+		result = value_fromwire(source, depth + 1, &value);
 		if (result != ISC_R_SUCCESS) {
 			isccc_sexpr_free(&list);
 			return (result);
@@ -699,7 +717,7 @@ isccc_cc_fromwire(isccc_region_t *source, isccc_sexpr_t **alistp,
 	if (version != 1)
 		return (ISCCC_R_UNKNOWNVERSION);
 
-	return (table_fromwire(source, secret, algorithm, alistp));
+	return (table_fromwire(source, secret, algorithm, 0, alistp));
 }
 
 static isc_result_t
diff --git a/lib/isccc/include/isccc/result.h b/lib/isccc/include/isccc/result.h
index 6c79dd7..a85861c 100644
--- a/lib/isccc/include/isccc/result.h
+++ b/lib/isccc/include/isccc/result.h
@@ -47,8 +47,10 @@
 #define ISCCC_R_CLOCKSKEW		(ISC_RESULTCLASS_ISCCC + 4)
 /*% Duplicate */
 #define ISCCC_R_DUPLICATE		(ISC_RESULTCLASS_ISCCC + 5)
+/*% Maximum recursion depth */
+#define ISCCC_R_MAXDEPTH               (ISC_RESULTCLASS_ISCCC + 6)
 
-#define ISCCC_R_NRESULTS 		6	/*%< Number of results */
+#define ISCCC_R_NRESULTS 		7	/*%< Number of results */
 
 ISC_LANG_BEGINDECLS
 
diff --git a/lib/isccc/result.c b/lib/isccc/result.c
index 8419bbb..325200b 100644
--- a/lib/isccc/result.c
+++ b/lib/isccc/result.c
@@ -40,7 +40,8 @@ static const char *text[ISCCC_R_NRESULTS] = {
 	"bad auth",				/* 3 */
 	"expired",				/* 4 */
 	"clock skew",				/* 5 */
-	"duplicate"				/* 6 */
+	"duplicate",				/* 6 */
+	"max depth",				/* 7 */
 };
 
 static const char *ids[ISCCC_R_NRESULTS] = {
@@ -50,6 +51,7 @@ static const char *ids[ISCCC_R_NRESULTS] = {
 	"ISCCC_R_EXPIRED",
 	"ISCCC_R_CLOCKSKEW",
 	"ISCCC_R_DUPLICATE",
+	"ISCCC_R_MAXDEPTH",
 };
 
 #define ISCCC_RESULT_RESULTSET			2
-- 
2.25.1