From owner-dev-commits-src-branches@freebsd.org Mon Aug 9 18:39:48 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id B975C6591D3; Mon, 9 Aug 2021 18:39:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Gk4d04wWqz3HCh; Mon, 9 Aug 2021 18:39:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 90A9351D2; Mon, 9 Aug 2021 18:39:48 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 179IdmMs069249; Mon, 9 Aug 2021 18:39:48 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 179IdmaQ069248; Mon, 9 Aug 2021 18:39:48 GMT (envelope-from git) Date: Mon, 9 Aug 2021 18:39:48 GMT Message-Id: <202108091839.179IdmaQ069248@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: 42cb78bdd49c - stable/12 - pf: bound DIOCGETSTATES memory use MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: 42cb78bdd49cd9a3e834c1ba3a00c7413917c812 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Aug 2021 18:39:48 -0000 The branch stable/12 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=42cb78bdd49cd9a3e834c1ba3a00c7413917c812 commit 42cb78bdd49cd9a3e834c1ba3a00c7413917c812 Author: Kristof Provost AuthorDate: 2021-08-02 07:46:33 +0000 Commit: Kristof Provost 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);