mirror of
https://github.com/systemd/systemd.git
synced 2025-01-24 06:04:05 +03:00
resolve: fix use after free in DnsAnswer
This fixes a bug introduced by ae45e1a3832fbb6c96707687e42f0b4aaab52c9b. The set DnsAnswer::set_items contains the reference to the array in DnsAnswer. So, the set must be reconstructed when we realloc() the object. Fixes #18132.
This commit is contained in:
parent
a084b38789
commit
0c2c0fd256
@ -664,6 +664,7 @@ int dns_answer_reserve(DnsAnswer **a, size_t n_free) {
|
||||
|
||||
if (*a) {
|
||||
size_t ns;
|
||||
int r;
|
||||
|
||||
if ((*a)->n_ref > 1)
|
||||
return -EBUSY;
|
||||
@ -680,11 +681,23 @@ int dns_answer_reserve(DnsAnswer **a, size_t n_free) {
|
||||
if (ns > UINT16_MAX)
|
||||
ns = UINT16_MAX;
|
||||
|
||||
/* This must be done before realloc() below. Otherwise, the original DnsAnswer object
|
||||
* may be broken. */
|
||||
r = set_reserve((*a)->set_items, ns);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n = realloc(*a, offsetof(DnsAnswer, items) + sizeof(DnsAnswerItem) * ns);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
n->n_allocated = ns;
|
||||
|
||||
/* Previously all items are stored in the set, and the enough memory area is allocated
|
||||
* in the above. So set_put() in the below cannot fail. */
|
||||
set_clear(n->set_items);
|
||||
for (size_t i = 0; i < n->n_rrs; i++)
|
||||
assert_se(set_put(n->set_items, &n->items[i]) > 0);
|
||||
} else {
|
||||
n = dns_answer_new(n_free);
|
||||
if (!n)
|
||||
|
Loading…
x
Reference in New Issue
Block a user