From nobody Fri Oct 27 08:35:18 2023 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 4SGww71FTdz4xyQH; Fri, 27 Oct 2023 08:35:19 +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 4SGww70Mzdz3TgF; Fri, 27 Oct 2023 08:35:19 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1698395719; 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=IhNpg+rcvH4YpzGSnDN3i8h/rjjZFctoBSS9OjJbVck=; b=QZNTqjl6RsD1vaxo4Sf8LSKTtANZzV3bY7t8NNzqEouciOE1EwNKHvDIvnoELdw7Q4uNSX QBVE4L/xKQfNr/70cMpiOzU8QtGYeRk4m0dM3fD1nR/aZNQT/5GRbb9ALuU9dflDQZFKqh qlaT8T0G2Yz6bnSSOmf8W1GyMUEL5M96zU4n3KlGfvK2w/0NxvOhb2eHz8owwcK2FJ1mIv jD3IxeK4TBO62TGY+tYLAkbAiNp92W9h5fWLiXr+U8Dx/ecUJidw7wMpE3aeFxteHBriQM PxjlF0BPAAq+SPIPm27a1Z08dbDsf1qRQvLVPxwFAYlzGrhyxx6A36l9tF5msQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1698395719; 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=IhNpg+rcvH4YpzGSnDN3i8h/rjjZFctoBSS9OjJbVck=; b=YX4ZudfEYTBfV902LWmHcCXHjcj7aCac+ZXeQSbugOtTuLRI3JfieoK3JpOZGU57y9g5Vz 1GV6yzuUz3g2OXsRWlSM8HtbeRzPvi5R2MfNjAPMDXXo0DVP0ECm+WMtX44aTqPhsxu5kN WzVsCvhxRpPTaps2LyrQQ+gaFmzLaZjIbhMYekVP7S4ZSCYaNd0SE7MGtnGE94GX1Cc3Fm q6ESb96tfRcskS/ikWlRpIiV4RX6E5en+hh8t4FNZgDUBmtTQVzsx6/OvJF4Zj8kO+kv+a eAHZtNOVsN+3r5/OCY0rRR9AxP7qpfrOTQJxY2eM8gagj4F7TDnGuRy6mpX0mQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1698395719; a=rsa-sha256; cv=none; b=wXx32invXlWnG224J2Umto0iVtprvYwUNm5N7NO/yD8NNZjiKDDCIFh5TBjkh7bq7Ivrn1 5iYh6IoRTnBU1pPnxJIFHng+k7kHGeoQfaty5P5aJnoDx0LO0iBESQwyiDC8qDrb6KuNJG 6K1L5l7lrbk1+9IunGE+Rn4Mp3G/u+ydb2bW+whNwHPomZKcOLQEOKsY+tpap1S/3JYP3Z jghwtT7cZJHNSttbWfWz/wDFLpQfNeyuIpi9Ix9/NVtS8ZSRzGID6EkO1X9XjSYKmO9P+O MMtQsXTLBKXlHrTlpUzTlZ6Udj41DKF/hlIlrWtucAS3na/l1TYR9IXJzw6Ctg== 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 4SGww6666sz168F; Fri, 27 Oct 2023 08:35:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 39R8ZIZV092041; Fri, 27 Oct 2023 08:35:18 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 39R8ZII4092038; Fri, 27 Oct 2023 08:35:18 GMT (envelope-from git) Date: Fri, 27 Oct 2023 08:35:18 GMT Message-Id: <202310270835.39R8ZII4092038@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: dfaadbb4661d - stable/13 - pfctl: fix incorrect mask on dynamic address 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/13 X-Git-Reftype: branch X-Git-Commit: dfaadbb4661de6d1a410205bf1e6653ca24f7610 Auto-Submitted: auto-generated The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=dfaadbb4661de6d1a410205bf1e6653ca24f7610 commit dfaadbb4661de6d1a410205bf1e6653ca24f7610 Author: Kristof Provost AuthorDate: 2023-10-06 12:20:17 +0000 Commit: Kristof Provost CommitDate: 2023-10-27 07:46:19 +0000 pfctl: fix incorrect mask on dynamic address A PF rule using an IPv4 address followed by an IPv6 address and then a dynamic address, e.g. "pass from {192.0.2.1 2001:db8::1} to (pppoe0)", will have an incorrect /32 mask applied to the dynamic address. MFC after: 3 weeks Obtained from: OpenBSD See also: https://ftp.openbsd.org/pub/OpenBSD/patches/5.6/common/007_pfctl.patch.sig Sponsored by: Rubicon Communications, LLC ("Netgate") Event: Oslo Hackathon at Modirum (cherry picked from commit 7ce98cf2f87a22240b66e4c38fd887431a25bf7d) --- sbin/pfctl/parse.y | 39 +++++++++++++++++++++++++++++++++++- sbin/pfctl/pfctl_parser.c | 30 ++++++++++++++++++++++----- sbin/pfctl/pfctl_parser.h | 1 + sbin/pfctl/tests/files/pf0102.ok | 4 ++-- sbin/pfctl/tests/files/pf1018.in | 1 + sbin/pfctl/tests/files/pf1018.ok | 2 ++ sbin/pfctl/tests/pfctl_test_list.inc | 1 + 7 files changed, 70 insertions(+), 8 deletions(-) diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index e0b9cdc1ee1f..6313e6dfcd15 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -4244,6 +4244,10 @@ natrule : nataction interface af proto fromto tag tagged rtable remove_invalid_hosts(&$9->host, &r.af); if (invalid_redirect($9->host, r.af)) YYERROR; + if ($9->host->addr.type == PF_ADDR_DYNIFTL) { + if (($9->host = gen_dynnode($9->host, r.af)) == NULL) + err(1, "calloc"); + } if (check_netmask($9->host, r.af)) YYERROR; @@ -4460,6 +4464,10 @@ binatrule : no BINAT natpasslog interface af proto FROM ipspec toipspec tag yyerror("binat ip versions must match"); YYERROR; } + if ($8->addr.type == PF_ADDR_DYNIFTL) { + if (($8 = gen_dynnode($8, binat.af)) == NULL) + err(1, "calloc"); + } if (check_netmask($8, binat.af)) YYERROR; memcpy(&binat.src.addr, &$8->addr, @@ -4475,6 +4483,10 @@ binatrule : no BINAT natpasslog interface af proto FROM ipspec toipspec tag yyerror("binat ip versions must match"); YYERROR; } + if ($9->addr.type == PF_ADDR_DYNIFTL) { + if (($9 = gen_dynnode($9, binat.af)) == NULL) + err(1, "calloc"); + } if (check_netmask($9, binat.af)) YYERROR; memcpy(&binat.dst.addr, &$9->addr, @@ -4504,6 +4516,10 @@ binatrule : no BINAT natpasslog interface af proto FROM ipspec toipspec tag "a single address"); YYERROR; } + if ($13->host->addr.type == PF_ADDR_DYNIFTL) { + if (($13->host = gen_dynnode($13->host, binat.af)) == NULL) + err(1, "calloc"); + } if (check_netmask($13->host, binat.af)) YYERROR; @@ -5412,7 +5428,7 @@ expand_rule(struct pfctl_rule *r, char tagname[PF_TAG_NAME_SIZE]; char match_tagname[PF_TAG_NAME_SIZE]; struct pf_pooladdr *pa; - struct node_host *h; + struct node_host *h, *osrch, *odsth; u_int8_t flags, flagset, keep_state; memcpy(label, r->label, sizeof(r->label)); @@ -5473,6 +5489,18 @@ expand_rule(struct pfctl_rule *r, sizeof(r->match_tagname)) >= sizeof(r->match_tagname)) errx(1, "expand_rule: strlcpy"); + osrch = odsth = NULL; + if (src_host->addr.type == PF_ADDR_DYNIFTL) { + osrch = src_host; + if ((src_host = gen_dynnode(src_host, r->af)) == NULL) + err(1, "expand_rule: calloc"); + } + if (dst_host->addr.type == PF_ADDR_DYNIFTL) { + odsth = dst_host; + if ((dst_host = gen_dynnode(dst_host, r->af)) == NULL) + err(1, "expand_rule: calloc"); + } + error += check_netmask(src_host, r->af); error += check_netmask(dst_host, r->af); @@ -5551,6 +5579,15 @@ expand_rule(struct pfctl_rule *r, added++; } + if (osrch && src_host->addr.type == PF_ADDR_DYNIFTL) { + free(src_host); + src_host = osrch; + } + if (odsth && dst_host->addr.type == PF_ADDR_DYNIFTL) { + free(dst_host); + dst_host = odsth; + } + )))))))))); FREE_LIST(struct node_if, interfaces); diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index c850056216ec..a3863cb23ac6 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1146,16 +1146,12 @@ int check_netmask(struct node_host *h, sa_family_t af) { struct node_host *n = NULL; - struct pf_addr *m; + struct pf_addr *m; for (n = h; n != NULL; n = n->next) { if (h->addr.type == PF_ADDR_TABLE) continue; m = &h->addr.v.a.mask; - /* fix up netmask for dynaddr */ - if (af == AF_INET && h->addr.type == PF_ADDR_DYNIFTL && - unmask(m, AF_INET6) > 32) - set_ipmask(n, 32); /* netmasks > 32 bit are invalid on v4 */ if (af == AF_INET && (m->addr32[1] || m->addr32[2] || m->addr32[3])) { @@ -1167,6 +1163,30 @@ check_netmask(struct node_host *h, sa_family_t af) return (0); } +struct node_host * +gen_dynnode(struct node_host *h, sa_family_t af) +{ + struct node_host *n; + struct pf_addr *m; + + if (h->addr.type != PF_ADDR_DYNIFTL) + return (NULL); + + if ((n = calloc(1, sizeof(*n))) == NULL) + return (NULL); + bcopy(h, n, sizeof(*n)); + n->ifname = NULL; + n->next = NULL; + n->tail = NULL; + + /* fix up netmask */ + m = &n->addr.v.a.mask; + if (af == AF_INET && unmask(m, AF_INET6) > 32) + set_ipmask(n, 32); + + return (n); +} + /* interface lookup routines */ static struct node_host *iftab; diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h index 06d52caf8e99..8cabf7e5bec2 100644 --- a/sbin/pfctl/pfctl_parser.h +++ b/sbin/pfctl/pfctl_parser.h @@ -340,6 +340,7 @@ extern const struct pf_timeout pf_timeouts[]; void set_ipmask(struct node_host *, u_int8_t); int check_netmask(struct node_host *, sa_family_t); int unmask(struct pf_addr *, sa_family_t); +struct node_host *gen_dynnode(struct node_host *, sa_family_t); void ifa_load(void); int get_query_socket(void); struct node_host *ifa_exists(char *); diff --git a/sbin/pfctl/tests/files/pf0102.ok b/sbin/pfctl/tests/files/pf0102.ok index 3233ca5a2643..1c76ec2725ba 100644 --- a/sbin/pfctl/tests/files/pf0102.ok +++ b/sbin/pfctl/tests/files/pf0102.ok @@ -1,8 +1,8 @@ pass inet from 1.1.1.1 to (self) flags S/SA keep state -pass inet6 from 2002:: to (self)/32 flags S/SA keep state +pass inet6 from 2002:: to (self) flags S/SA keep state pass inet6 from 2002:: to (self) flags S/SA keep state pass inet from 1.1.1.1 to (self) flags S/SA keep state pass inet from 1.1.1.1 to (self) flags S/SA keep state -pass inet6 from 2002:: to (self)/32 flags S/SA keep state +pass inet6 from 2002:: to (self)/40 flags S/SA keep state pass inet6 from 2002:: to (self)/40 flags S/SA keep state pass inet from 1.1.1.1 to (self) flags S/SA keep state diff --git a/sbin/pfctl/tests/files/pf1018.in b/sbin/pfctl/tests/files/pf1018.in new file mode 100644 index 000000000000..90f0a3a0bab7 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1018.in @@ -0,0 +1 @@ +pass from { 192.0.2.1 2001:db8::1 } to (pppoe0) diff --git a/sbin/pfctl/tests/files/pf1018.ok b/sbin/pfctl/tests/files/pf1018.ok new file mode 100644 index 000000000000..04950f0035b8 --- /dev/null +++ b/sbin/pfctl/tests/files/pf1018.ok @@ -0,0 +1,2 @@ +pass inet from 192.0.2.1 to (pppoe0) flags S/SA keep state +pass inet6 from 2001:db8::1 to (pppoe0) flags S/SA keep state diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc index 0def88f4d7e1..b73bcf2522b7 100644 --- a/sbin/pfctl/tests/pfctl_test_list.inc +++ b/sbin/pfctl/tests/pfctl_test_list.inc @@ -116,3 +116,4 @@ PFCTL_TEST(1004, "ALTQ with Codel") PFCTL_TEST(1005, "PR 231323") PFCTL_TEST(1006, "pfctl crashes with certain fairq configurations") PFCTL_TEST(1010, "POM_STICKYADDRESS test") +PFCTL_TEST(1018, "Test dynamic address mask")