git: 18fb9174cda5 - stable/14 - netlink: fix snl_writer and linear_buffer re-allocation logic
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 27 Dec 2023 21:06:17 UTC
The branch stable/14 has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=18fb9174cda527f107c072fb87aef72be4939da7
commit 18fb9174cda527f107c072fb87aef72be4939da7
Author: Igor Ostapenko <pm@igoro.pro>
AuthorDate: 2023-12-12 18:26:21 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-12-27 21:01:38 +0000
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:
ffbf25951e7b ("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
(cherry picked from commit 0c511bafdd5b309505c13c8dc7c6816686d1e103)
---
sys/netlink/netlink_snl.h | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h
index 8bb7b076b7b7..7bdf5424ddf3 100644
--- a/sys/netlink/netlink_snl.h
+++ b/sys/netlink/netlink_snl.h
@@ -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);
}