From owner-dev-commits-src-branches@freebsd.org Fri Jul 16 11:54:02 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 820B9660503; Fri, 16 Jul 2021 11:54:02 +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 4GR8ls64yFz4qqC; Fri, 16 Jul 2021 11:54:01 +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 5CE761CB93; Fri, 16 Jul 2021 11:54:01 +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 16GBs1Tt016311; Fri, 16 Jul 2021 11:54:01 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 16GBs1M8016310; Fri, 16 Jul 2021 11:54:01 GMT (envelope-from git) Date: Fri, 16 Jul 2021 11:54:01 GMT Message-Id: <202107161154.16GBs1M8016310@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: 569798e0824a - stable/13 - pf: bound DIOCGETSTATESV2 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/13 X-Git-Reftype: branch X-Git-Commit: 569798e0824a61f7f5308da4619322110523471b 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: Fri, 16 Jul 2021 11:54:02 -0000 The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=569798e0824a61f7f5308da4619322110523471b commit 569798e0824a61f7f5308da4619322110523471b Author: Kristof Provost AuthorDate: 2021-07-08 13:01:19 +0000 Commit: Kristof Provost CommitDate: 2021-07-16 09:08:28 +0000 pf: bound DIOCGETSTATESV2 memory use Rather than allocating however much memory userspace asks for we only allocate enough for a handful of states, and copy to userspace for each completed row. We start out with enough space for 16 states (per row), but grow that as required. In most configurations we expect at most a handful of states per row (more than that would have other negative effects on packet processing performance). Reviewed by: mjg MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D31111 (cherry picked from commit 3fc12ae042040192aa43984106a75663aaa9e0f5) --- sys/netpfil/pf/pf_ioctl.c | 48 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 24e40c1c716c..c9105bf22385 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2879,6 +2879,8 @@ DIOCGETSTATES_full: struct pf_kstate *s; struct pf_state_export *pstore, *p; int i, nr; + size_t slice_count = 16, count; + void *out; if (ps->ps_req_version > PF_STATE_VERSION) { error = ENOTSUP; @@ -2891,38 +2893,60 @@ DIOCGETSTATES_full: break; } - p = pstore = malloc(ps->ps_len, M_TEMP, M_WAITOK | M_ZERO); + out = ps->ps_states; + pstore = mallocarray(slice_count, + sizeof(struct pf_state_export), M_TEMP, M_WAITOK | M_ZERO); nr = 0; for (i = 0; i <= pf_hashmask; i++) { struct pf_idhash *ih = &V_pf_idhash[i]; +DIOCGETSTATESV2_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 pf_state_export), M_TEMP, + M_WAITOK | M_ZERO); + goto DIOCGETSTATESV2_retry; + } + + if ((nr+count) * sizeof(*p) > ps->ps_len) { + PF_HASHROW_UNLOCK(ih); + goto DIOCGETSTATESV2_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 DIOCGETSTATESV2_full; - } pf_state_export(p, s); p++; nr++; } PF_HASHROW_UNLOCK(ih); + error = copyout(pstore, out, + sizeof(struct pf_state_export) * count); + if (error) + break; + out = ps->ps_states + nr; } DIOCGETSTATESV2_full: - error = copyout(pstore, ps->ps_states, - sizeof(struct pf_state_export) * nr); - if (error) { - free(pstore, M_TEMP); - break; - } - ps->ps_len = sizeof(struct pf_state_export) * nr; + ps->ps_len = nr * sizeof(struct pf_state_export); free(pstore, M_TEMP); break;