Date: Mon, 9 Aug 2021 18:39:48 GMT From: Kristof Provost <kp@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 42cb78bdd49c - stable/12 - pf: bound DIOCGETSTATES memory use Message-ID: <202108091839.179IdmaQ069248@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=42cb78bdd49cd9a3e834c1ba3a00c7413917c812 commit 42cb78bdd49cd9a3e834c1ba3a00c7413917c812 Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2021-08-02 07:46:33 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2021-08-09 15:57:23 +0000 pf: bound DIOCGETSTATES memory use Similar to what we did earlier for DIOCGETSTATESV2 we only allocate enough memory for a handful of states and copy those out, bit by bit, rather than allocating memory for all states in one go. MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") (cherry picked from commit 600745f1e2260e7ed3c2e6183b24388ff38c916c) --- sys/netpfil/pf/pf_ioctl.c | 51 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 8a6286b5c21a..ea323709f6cd 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2852,7 +2852,9 @@ DIOCCHANGERULE_error: struct pfioc_states *ps = (struct pfioc_states *)addr; struct pf_kstate *s; struct pfsync_state *pstore, *p; - int i, nr; + int i, nr; + size_t slice_count = 16, count; + void *out; if (ps->ps_len <= 0) { nr = uma_zone_get_cur(V_pf_state_z); @@ -2860,35 +2862,60 @@ DIOCCHANGERULE_error: break; } - p = pstore = malloc(ps->ps_len, M_TEMP, M_WAITOK | M_ZERO); + out = ps->ps_states; + pstore = mallocarray(slice_count, + sizeof(struct pfsync_state), M_TEMP, M_WAITOK | M_ZERO); nr = 0; for (i = 0; i <= pf_hashmask; i++) { struct pf_idhash *ih = &V_pf_idhash[i]; +DIOCGETSTATES_retry: + p = pstore; + + if (LIST_EMPTY(&ih->states)) + continue; + PF_HASHROW_LOCK(ih); + count = 0; + LIST_FOREACH(s, &ih->states, entry) { + if (s->timeout == PFTM_UNLINKED) + continue; + count++; + } + + if (count > slice_count) { + PF_HASHROW_UNLOCK(ih); + free(pstore, M_TEMP); + slice_count = count * 2; + pstore = mallocarray(slice_count, + sizeof(struct pfsync_state), M_TEMP, + M_WAITOK | M_ZERO); + goto DIOCGETSTATES_retry; + } + + if ((nr+count) * sizeof(*p) > ps->ps_len) { + PF_HASHROW_UNLOCK(ih); + goto DIOCGETSTATES_full; + } + LIST_FOREACH(s, &ih->states, entry) { if (s->timeout == PFTM_UNLINKED) continue; - if ((nr+1) * sizeof(*p) > ps->ps_len) { - PF_HASHROW_UNLOCK(ih); - goto DIOCGETSTATES_full; - } pfsync_state_export(p, s); p++; nr++; } PF_HASHROW_UNLOCK(ih); + error = copyout(pstore, out, + sizeof(struct pfsync_state) * count); + if (error) + break; + out = ps->ps_states + nr; } DIOCGETSTATES_full: - error = copyout(pstore, ps->ps_states, - sizeof(struct pfsync_state) * nr); - if (error) { - free(pstore, M_TEMP); - break; - } ps->ps_len = sizeof(struct pfsync_state) * nr; free(pstore, M_TEMP);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108091839.179IdmaQ069248>