From nobody Wed May 4 12:50:29 2022 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4BAE41AAA2D9; Wed, 4 May 2022 12:50:30 +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 4KtcBF4WPXz569W; Wed, 4 May 2022 12:50:29 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1651668629; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=R6Vm625QOmbKz+iKE8IpeBeq9m2ZKnW87tNZiAP9QEk=; b=IRZ2OwlBhipUP3RZhklkUsaMpBXzddJLtfUle9k1nfGiuSGgskql5DqR608vlnPgNsJmDv gCT3EzNj3DcRIX39GtB2MOTP9S7V5pqudC7LbLaaBcob3nQWx0ZdLpPvWLyfWEOolk/F9g KpHYYMgwWhoYCfLjA7NFdvSrvkCPiPqbIs8Kl0r5NtYC4Wr10N7unsCmz/SieKNByviXKh 8h9cpEMLiuUTcU3ttKdRvbQVFtqdE9iE8cwh9Xs0NUtpTUcI9tup53Yy30Y5j/Z/VOHZxM XbEGmEYCuiFLf9A5Vsd7I1fl7YWX/l8IfLJGQvdr7vomlNegDKJxsL1HLd64jg== 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 6489813414; Wed, 4 May 2022 12:50:29 +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 244CoTxb024270; Wed, 4 May 2022 12:50:29 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 244CoT4r024269; Wed, 4 May 2022 12:50:29 GMT (envelope-from git) Date: Wed, 4 May 2022 12:50:29 GMT Message-Id: <202205041250.244CoT4r024269@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: 7f55abdaa92c - stable/12 - libpfctl: grow request buffer on ENOSPC List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org 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: 7f55abdaa92ca06bd5eb6d3d321e776b9770f9c2 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1651668629; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=R6Vm625QOmbKz+iKE8IpeBeq9m2ZKnW87tNZiAP9QEk=; b=bhGnP2R8ak4tTVEL5n7zEjyjXEvVTN4KLeiar5B/fBk4gSp9xmfuXx7OfDEb0gRyAyNvTC J6lRXvu56DqAllWTW2ZBwwyrG0zdXkXlVkzdZ58joJyzMxzA3a4pSJhYqSZqgOCLZ6Z9+m cVOWcY6ZcSltqtA6y9zFTVCzCjo/igyK6Apuj5kRuhSJcQWABcxk4pdAOsChGew1PYplcv AjlHftT437wYMVLgCa/xT8gIqKJvL+ukWkQPaFmR08daYYQg0/xmdsPLNKid7h2YRa9ohR pMwsMpLsNbUk3t1ePNOIJatizQsdmG/EajJG7MUrWPEkKBDS8050RYe7222Cfw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1651668629; a=rsa-sha256; cv=none; b=HmzEpXGVWireD7Vu6sR4sSWDIAhFRTiOcZeex8GYLZ/WRu5/ReqSW4Xrz8mzQJlm4pOFQh FUJtoBEjxKmA5WrLHUzSBlGTkYoYLxAvF0ch3QtNsos8JUlzvorsqA5+bYk/32gU33RY08 hBQMhx8h1vdDMmGw+NV+Bd+pkyMABU4tSEGeLZ7JQiw6VWDHyiZgmmiNOINRvCHQN5GOWD Qfrev74ox/3TG+nKcGH8OmAnISXYVxJGACtd78CiFYtlp+GfOlmhy1ZHjZNZFmPJxgupQV tUjF+0wHKr3quxPpjoCR757734vV81WPig47FhQS+EKtyjriC8TJTcY23W5xcQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/12 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=7f55abdaa92ca06bd5eb6d3d321e776b9770f9c2 commit 7f55abdaa92ca06bd5eb6d3d321e776b9770f9c2 Author: Kristof Provost AuthorDate: 2022-04-14 12:08:53 +0000 Commit: Kristof Provost CommitDate: 2022-05-04 12:49:50 +0000 libpfctl: grow request buffer on ENOSPC When we issue a request to pf and expect a serialised nvlist as a reply we have to supply a suitable buffer to the kernel. The required size for this buffer is difficult to predict, and may be (slightly) different from request to request. If it's insufficient the kernel will return ENOSPC. Teach libpfctl to catch this and send the request again with a larger buffer. MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D34908 (cherry picked from commit 7ed19f5c7780ebe9ec67121f0c5aa19fbc80bf1a) --- lib/libpfctl/libpfctl.c | 114 +++++++++++++++++++++--------------------------- 1 file changed, 49 insertions(+), 65 deletions(-) diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index 638f1de7a070..99ca563548c9 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -59,6 +59,49 @@ const char* PFCTL_SYNCOOKIES_MODE_NAMES[] = { static int _pfctl_clear_states(int , const struct pfctl_kill *, unsigned int *, uint64_t); +static int +pfctl_do_ioctl(int dev, uint cmd, size_t size, nvlist_t **nvl) +{ + struct pfioc_nv nv; + void *data; + size_t nvlen; + int ret; + + data = nvlist_pack(*nvl, &nvlen); + +retry: + nv.data = malloc(size); + memcpy(nv.data, data, nvlen); + free(data); + + nv.len = nvlen; + nv.size = size; + + ret = ioctl(dev, cmd, &nv); + if (ret == -1 && errno == ENOSPC) { + size *= 2; + free(nv.data); + goto retry; + } + + nvlist_destroy(*nvl); + *nvl = NULL; + + if (ret == 0) { + *nvl = nvlist_unpack(nv.data, nv.len, 0); + if (*nvl == NULL) { + free(nv.data); + return (EIO); + } + } else { + ret = errno; + } + + free(nv.data); + + return (ret); +} + static void pf_nvuint_8_array(const nvlist_t *nvl, const char *name, size_t maxelems, uint8_t *numbers, size_t *nelems) @@ -159,7 +202,6 @@ _pfctl_get_status_counters(const nvlist_t *nvl, struct pfctl_status * pfctl_get_status(int dev) { - struct pfioc_nv nv; struct pfctl_status *status; nvlist_t *nvl; size_t len; @@ -169,18 +211,9 @@ pfctl_get_status(int dev) if (status == NULL) return (NULL); - nv.data = malloc(4096); - nv.len = nv.size = 4096; - - if (ioctl(dev, DIOCGETSTATUSNV, &nv)) { - free(nv.data); - free(status); - return (NULL); - } + nvl = nvlist_create(0); - nvl = nvlist_unpack(nv.data, nv.len, 0); - free(nv.data); - if (nvl == NULL) { + if (pfctl_do_ioctl(dev, DIOCGETSTATUSNV, 4096, &nvl)) { free(status); return (NULL); } @@ -695,9 +728,7 @@ int pfctl_get_clear_rule(int dev, uint32_t nr, uint32_t ticket, const char *anchor, uint32_t ruleset, struct pfctl_rule *rule, char *anchor_call, bool clear) { - struct pfioc_nv nv; nvlist_t *nvl; - void *nvlpacked; int ret; nvl = nvlist_create(0); @@ -712,30 +743,8 @@ int pfctl_get_clear_rule(int dev, uint32_t nr, uint32_t ticket, if (clear) nvlist_add_bool(nvl, "clear_counter", true); - nvlpacked = nvlist_pack(nvl, &nv.len); - if (nvlpacked == NULL) { - nvlist_destroy(nvl); - return (ENOMEM); - } - nv.data = malloc(8182); - nv.size = 8192; - assert(nv.len <= nv.size); - memcpy(nv.data, nvlpacked, nv.len); - nvlist_destroy(nvl); - nvl = NULL; - free(nvlpacked); - - ret = ioctl(dev, DIOCGETRULENV, &nv); - if (ret != 0) { - free(nv.data); + if ((ret = pfctl_do_ioctl(dev, DIOCGETRULENV, 8192, &nvl)) != 0) return (ret); - } - - nvl = nvlist_unpack(nv.data, nv.len, 0); - if (nvl == NULL) { - free(nv.data); - return (EIO); - } pf_nvrule_to_rule(nvlist_get_nvlist(nvl, "rule"), rule); @@ -743,7 +752,6 @@ int pfctl_get_clear_rule(int dev, uint32_t nr, uint32_t ticket, strlcpy(anchor_call, nvlist_get_string(nvl, "anchor_call"), MAXPATHLEN); - free(nv.data); nvlist_destroy(nvl); return (0); @@ -929,22 +937,8 @@ _pfctl_clear_states(int dev, const struct pfctl_kill *kill, nvlist_add_string(nvl, "label", kill->label); nvlist_add_bool(nvl, "kill_match", kill->kill_match); - nv.data = nvlist_pack(nvl, &nv.len); - nv.size = nv.len; - nvlist_destroy(nvl); - nvl = NULL; - - ret = ioctl(dev, ioctlval, &nv); - if (ret != 0) { - free(nv.data); + if ((ret = pfctl_do_ioctl(dev, ioctlval, 1024, &nvl)) != 0) return (ret); - } - - nvl = nvlist_unpack(nv.data, nv.len, 0); - if (nvl == NULL) { - free(nv.data); - return (EIO); - } if (killed) *killed = nvlist_get_number(nvl, "killed"); @@ -1082,7 +1076,6 @@ pfctl_set_syncookies(int dev, const struct pfctl_syncookies *s) int pfctl_get_syncookies(int dev, struct pfctl_syncookies *s) { - struct pfioc_nv nv; nvlist_t *nvl; int ret; uint state_limit; @@ -1094,19 +1087,10 @@ pfctl_get_syncookies(int dev, struct pfctl_syncookies *s) bzero(s, sizeof(*s)); - nv.data = malloc(256); - nv.len = nv.size = 256; + nvl = nvlist_create(0); - if (ioctl(dev, DIOCGETSYNCOOKIES, &nv)) { - free(nv.data); + if ((ret = pfctl_do_ioctl(dev, DIOCGETSYNCOOKIES, 256, &nvl)) != 0) return (errno); - } - - nvl = nvlist_unpack(nv.data, nv.len, 0); - free(nv.data); - if (nvl == NULL) { - return (EIO); - } enabled = nvlist_get_bool(nvl, "enabled"); adaptive = nvlist_get_bool(nvl, "adaptive");