diff options
Diffstat (limited to 'meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch')
-rw-r--r-- | meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch | 166 |
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 | |||
2 | Upstream-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 | ||
3 | Upstream patch https://downloads.isc.org/isc/bind9/9.16.42/patches/0001-CVE-2023-2828.patch] | ||
4 | Upstream Commit: https://github.com/isc-projects/bind9/commit/da0eafcdee52147e72d407cc3b9f179378ee1d3a | ||
5 | CVE: CVE-2023-2828 | ||
6 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
7 | |||
8 | --- | ||
9 | lib/dns/rbtdb.c | 106 +++++++++++++++++++++++++++++++++----------------------- | ||
10 | 1 file changed, 63 insertions(+), 43 deletions(-) | ||
11 | |||
12 | diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c | ||
13 | index 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); | ||