aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2021-04-24 13:55:24 +0000
committerKristof Provost <kp@FreeBSD.org>2021-05-10 19:46:06 +0000
commit39ed63e074892f49e7c458715b08fc4f604ebcea (patch)
tree1490bc3d852ee4f89b81ac07330d5ca74ad839f9
parent304e740b7ea89c508efa5e47cbd9317d41e8e52f (diff)
pf: Fix parsing of long table names
When parsing the nvlist for a struct pf_addr_wrap we unconditionally tried to parse "ifname". This broke for PF_ADDR_TABLE when the table name was longer than IFNAMSIZ. PF_TABLE_NAME_SIZE is longer than IFNAMSIZ, so this is a valid configuration. Only parse (or return) ifname or tblname for the corresponding pf_addr_wrap type. This manifested as a failure to set rules such as these, where the pfctl optimiser generated an automatic table: pass in proto tcp to 192.168.0.1 port ssh pass in proto tcp to 192.168.0.2 port ssh pass in proto tcp to 192.168.0.3 port ssh pass in proto tcp to 192.168.0.4 port ssh pass in proto tcp to 192.168.0.5 port ssh pass in proto tcp to 192.168.0.6 port ssh pass in proto tcp to 192.168.0.7 port ssh Reported by: Florian Smeets Tested by: Florian Smeets Reviewed by: donner X-MFC-With: 5c11c5a3655842a176124ef2334fcdf830422c8a MFC after: 2 weeks Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D29962 (cherry picked from commit 402dfb0a8d2c6417cb9bff4460ef250a42b0aa05)
-rw-r--r--lib/libpfctl/libpfctl.c15
-rw-r--r--sys/netpfil/pf/pf_ioctl.c16
2 files changed, 20 insertions, 11 deletions
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 6d5397cb64b2..69c51ec6c897 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -148,8 +148,10 @@ pfctl_nv_add_addr_wrap(nvlist_t *nvparent, const char *name,
nvlist_add_number(nvl, "type", addr->type);
nvlist_add_number(nvl, "iflags", addr->iflags);
- nvlist_add_string(nvl, "ifname", addr->v.ifname);
- nvlist_add_string(nvl, "tblname", addr->v.tblname);
+ if (addr->type == PF_ADDR_DYNIFTL)
+ nvlist_add_string(nvl, "ifname", addr->v.ifname);
+ if (addr->type == PF_ADDR_TABLE)
+ nvlist_add_string(nvl, "tblname", addr->v.tblname);
pfctl_nv_add_addr(nvl, "addr", &addr->v.a.addr);
pfctl_nv_add_addr(nvl, "mask", &addr->v.a.mask);
@@ -161,9 +163,12 @@ pf_nvaddr_wrap_to_addr_wrap(const nvlist_t *nvl, struct pf_addr_wrap *addr)
{
addr->type = nvlist_get_number(nvl, "type");
addr->iflags = nvlist_get_number(nvl, "iflags");
- strlcpy(addr->v.ifname, nvlist_get_string(nvl, "ifname"), IFNAMSIZ);
- strlcpy(addr->v.tblname, nvlist_get_string(nvl, "tblname"),
- PF_TABLE_NAME_SIZE);
+ if (addr->type == PF_ADDR_DYNIFTL)
+ strlcpy(addr->v.ifname, nvlist_get_string(nvl, "ifname"),
+ IFNAMSIZ);
+ if (addr->type == PF_ADDR_TABLE)
+ strlcpy(addr->v.tblname, nvlist_get_string(nvl, "tblname"),
+ PF_TABLE_NAME_SIZE);
pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "addr"), &addr->v.a.addr);
pf_nvaddr_to_addr(nvlist_get_nvlist(nvl, "mask"), &addr->v.a.mask);
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 99bf8efcca1a..1eaad66b2cdb 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -1704,10 +1704,12 @@ pf_nvaddr_wrap_to_addr_wrap(const nvlist_t *nvl, struct pf_addr_wrap *addr)
PFNV_CHK(pf_nvuint8(nvl, "type", &addr->type));
PFNV_CHK(pf_nvuint8(nvl, "iflags", &addr->iflags));
- PFNV_CHK(pf_nvstring(nvl, "ifname", addr->v.ifname,
- sizeof(addr->v.ifname)));
- PFNV_CHK(pf_nvstring(nvl, "tblname", addr->v.tblname,
- sizeof(addr->v.tblname)));
+ if (addr->type == PF_ADDR_DYNIFTL)
+ PFNV_CHK(pf_nvstring(nvl, "ifname", addr->v.ifname,
+ sizeof(addr->v.ifname)));
+ if (addr->type == PF_ADDR_TABLE)
+ PFNV_CHK(pf_nvstring(nvl, "tblname", addr->v.tblname,
+ sizeof(addr->v.tblname)));
if (! nvlist_exists_nvlist(nvl, "addr"))
return (EINVAL);
@@ -1747,8 +1749,10 @@ pf_addr_wrap_to_nvaddr_wrap(const struct pf_addr_wrap *addr)
nvlist_add_number(nvl, "type", addr->type);
nvlist_add_number(nvl, "iflags", addr->iflags);
- nvlist_add_string(nvl, "ifname", addr->v.ifname);
- nvlist_add_string(nvl, "tblname", addr->v.tblname);
+ if (addr->type == PF_ADDR_DYNIFTL)
+ nvlist_add_string(nvl, "ifname", addr->v.ifname);
+ if (addr->type == PF_ADDR_TABLE)
+ nvlist_add_string(nvl, "tblname", addr->v.tblname);
tmp = pf_addr_to_nvaddr(&addr->v.a.addr);
if (tmp == NULL)