summaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch')
-rw-r--r--meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch166
1 files changed, 166 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch b/meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch
new file mode 100644
index 0000000000..6f6c104530
--- /dev/null
+++ b/meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch
@@ -0,0 +1,166 @@
1
2Upstream-Status: Backport [import from debian security.debian.org/debian-security/pool/updates/main/b/bind9/bind9_9.11.5.P4+dfsg-5.1+deb10u9.debian.tar.xz
3Upstream patch https://downloads.isc.org/isc/bind9/9.16.42/patches/0001-CVE-2023-2828.patch]
4Upstream Commit: https://github.com/isc-projects/bind9/commit/da0eafcdee52147e72d407cc3b9f179378ee1d3a
5CVE: CVE-2023-2828
6Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
7
8---
9 lib/dns/rbtdb.c | 106 +++++++++++++++++++++++++++++++++-----------------------
10 1 file changed, 63 insertions(+), 43 deletions(-)
11
12diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
13index b1b928c..3165e26 100644
14--- a/lib/dns/rbtdb.c
15+++ b/lib/dns/rbtdb.c
16@@ -792,7 +792,7 @@ static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
17 static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
18 bool tree_locked, expire_t reason);
19 static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
20- isc_stdtime_t now, bool tree_locked);
21+ size_t purgesize, bool tree_locked);
22 static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx,
23 rdatasetheader_t *newheader);
24 static void resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
25@@ -6784,6 +6784,16 @@ addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
26
27 static dns_dbmethods_t zone_methods;
28
29+static size_t
30+rdataset_size(rdatasetheader_t *header) {
31+ if (!NONEXISTENT(header)) {
32+ return (dns_rdataslab_size((unsigned char *)header,
33+ sizeof(*header)));
34+ }
35+
36+ return (sizeof(*header));
37+}
38+
39 static isc_result_t
40 addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
41 isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
42@@ -6932,7 +6942,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
43 }
44
45 if (cache_is_overmem)
46- overmem_purge(rbtdb, rbtnode->locknum, now, tree_locked);
47+ overmem_purge(rbtdb, rbtnode->locknum, rdataset_size(newheader),
48+ tree_locked);
49
50 NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
51 isc_rwlocktype_write);
52@@ -6947,9 +6958,14 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
53 cleanup_dead_nodes(rbtdb, rbtnode->locknum);
54
55 header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
56- if (header && header->rdh_ttl < now - RBTDB_VIRTUAL)
57- expire_header(rbtdb, header, tree_locked,
58- expire_ttl);
59+ if (header != NULL) {
60+ dns_ttl_t rdh_ttl = header->rdh_ttl;
61+
62+ if (rdh_ttl < now - RBTDB_VIRTUAL) {
63+ expire_header(rbtdb, header, tree_locked,
64+ expire_ttl);
65+ }
66+ }
67
68 /*
69 * If we've been holding a write lock on the tree just for
70@@ -10388,54 +10404,58 @@ update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
71 ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link);
72 }
73
74+static size_t
75+expire_lru_headers(dns_rbtdb_t *rbtdb, unsigned int locknum, size_t purgesize,
76+ bool tree_locked) {
77+ rdatasetheader_t *header, *header_prev;
78+ size_t purged = 0;
79+
80+ for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
81+ header != NULL && purged <= purgesize; header = header_prev)
82+ {
83+ header_prev = ISC_LIST_PREV(header, link);
84+ /*
85+ * Unlink the entry at this point to avoid checking it
86+ * again even if it's currently used someone else and
87+ * cannot be purged at this moment. This entry won't be
88+ * referenced any more (so unlinking is safe) since the
89+ * TTL was reset to 0.
90+ */
91+ ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header, link);
92+ size_t header_size = rdataset_size(header);
93+ expire_header(rbtdb, header, tree_locked, expire_lru);
94+ purged += header_size;
95+ }
96+
97+ return (purged);
98+}
99+
100 /*%
101- * Purge some expired and/or stale (i.e. unused for some period) cache entries
102- * under an overmem condition. To recover from this condition quickly, up to
103- * 2 entries will be purged. This process is triggered while adding a new
104- * entry, and we specifically avoid purging entries in the same LRU bucket as
105- * the one to which the new entry will belong. Otherwise, we might purge
106- * entries of the same name of different RR types while adding RRsets from a
107- * single response (consider the case where we're adding A and AAAA glue records
108- * of the same NS name).
109- */
110+ * Purge some stale (i.e. unused for some period - LRU based cleaning) cache
111+ * entries under the overmem condition. To recover from this condition quickly,
112+ * we cleanup entries up to the size of newly added rdata (passed as purgesize).
113+ *
114+ * This process is triggered while adding a new entry, and we specifically avoid
115+ * purging entries in the same LRU bucket as the one to which the new entry will
116+ * belong. Otherwise, we might purge entries of the same name of different RR
117+ * types while adding RRsets from a single response (consider the case where
118+ * we're adding A and AAAA glue records of the same NS name).
119+*/
120 static void
121-overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
122- isc_stdtime_t now, bool tree_locked)
123+overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, size_t purgesize,
124+ bool tree_locked)
125 {
126- rdatasetheader_t *header, *header_prev;
127 unsigned int locknum;
128- int purgecount = 2;
129+ size_t purged = 0;
130
131 for (locknum = (locknum_start + 1) % rbtdb->node_lock_count;
132- locknum != locknum_start && purgecount > 0;
133+ locknum != locknum_start && purged <= purgesize;
134 locknum = (locknum + 1) % rbtdb->node_lock_count) {
135 NODE_LOCK(&rbtdb->node_locks[locknum].lock,
136 isc_rwlocktype_write);
137
138- header = isc_heap_element(rbtdb->heaps[locknum], 1);
139- if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) {
140- expire_header(rbtdb, header, tree_locked,
141- expire_ttl);
142- purgecount--;
143- }
144-
145- for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
146- header != NULL && purgecount > 0;
147- header = header_prev) {
148- header_prev = ISC_LIST_PREV(header, link);
149- /*
150- * Unlink the entry at this point to avoid checking it
151- * again even if it's currently used someone else and
152- * cannot be purged at this moment. This entry won't be
153- * referenced any more (so unlinking is safe) since the
154- * TTL was reset to 0.
155- */
156- ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header,
157- link);
158- expire_header(rbtdb, header, tree_locked,
159- expire_lru);
160- purgecount--;
161- }
162+ purged += expire_lru_headers(rbtdb, locknum, purgesize - purged,
163+ tree_locked);
164
165 NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
166 isc_rwlocktype_write);