netlink: fix snl_writer and linear_buffer re-allocation logic

- Use the correct base pointer after re-allocation to avoid buffer
  overflows.

- Maintain correct snl_writer.size, which avoids redundant memory
  allocation, e.g. a need for ~1k bytes may end up with ~32k
  linear_buffer actually allocated.

This fixes a pfctl regression at least for armv7 after the addrule logic
migration to netlink:
  ffbf25951e ("pf: convert rule addition to netlink")

The add rule command creates a bigger than default size netlink requests
which triggers the re-allocation logic.

Reviewed by:	kp
MFC after:	2 weeks
Differnetial Revision:	https://reviews.freebsd.org/D43003
This commit is contained in:
Igor Ostapenko 2023-12-12 19:26:21 +01:00 committed by Kristof Provost
parent 6fa843f6e6
commit 0c511bafdd

View file

@ -1036,19 +1036,23 @@ snl_realloc_msg_buffer(struct snl_writer *nw, size_t sz)
if (nw->error)
return (false);
void *new_base = snl_allocz(nw->ss, new_size);
if (new_base == NULL) {
if (snl_allocz(nw->ss, new_size) == NULL) {
nw->error = true;
return (false);
}
nw->size = new_size;
memcpy(new_base, nw->base, nw->offset);
if (nw->hdr != NULL) {
int hdr_off = (char *)(nw->hdr) - nw->base;
void *new_base = nw->ss->lb->base;
if (new_base != nw->base) {
memcpy(new_base, nw->base, nw->offset);
if (nw->hdr != NULL) {
int hdr_off = (char *)(nw->hdr) - nw->base;
nw->hdr = (struct nlmsghdr *)(void *)((char *)new_base + hdr_off);
nw->hdr = (struct nlmsghdr *)
(void *)((char *)new_base + hdr_off);
}
nw->base = new_base;
}
nw->base = new_base;
return (true);
}