From owner-dev-commits-src-all@freebsd.org Mon Aug 2 16:30:26 2021 Return-Path: Delivered-To: dev-commits-src-all@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 DD83467716E; Mon, 2 Aug 2021 16:30:26 +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 4Gdk4y5x2rz4gnT; Mon, 2 Aug 2021 16:30:26 +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 B3D5C22B53; Mon, 2 Aug 2021 16:30:26 +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 172GUQa3087069; Mon, 2 Aug 2021 16:30:26 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 172GUQQJ087068; Mon, 2 Aug 2021 16:30:26 GMT (envelope-from git) Date: Mon, 2 Aug 2021 16:30:26 GMT Message-Id: <202108021630.172GUQQJ087068@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kristof Provost Subject: git: 600745f1e226 - main - 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/main X-Git-Reftype: branch X-Git-Commit: 600745f1e2260e7ed3c2e6183b24388ff38c916c Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 02 Aug 2021 16:30:26 -0000 The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=600745f1e2260e7ed3c2e6183b24388ff38c916c commit 600745f1e2260e7ed3c2e6183b24388ff38c916c Author: Kristof Provost AuthorDate: 2021-08-02 07:46:33 +0000 Commit: Kristof Provost CommitDate: 2021-08-02 14:29: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") --- 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 7c506b79295b..b2d7fc33d8b8 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2916,7 +2916,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); @@ -2924,34 +2926,59 @@ 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);