summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netpfil
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-21 13:47:02 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:41 +0200
commitbcdce02d9bc8150e1d191ed5ca9da45b7604964a (patch)
tree3b2faf509db7672ee1fc98857736470be97e7ed8 /freebsd/sys/netpfil
parentUpdate to FreeBSD head 2018-04-01 (diff)
downloadrtems-libbsd-bcdce02d9bc8150e1d191ed5ca9da45b7604964a.tar.bz2
Update to FreeBSD head 2018-06-01
Git mirror commit fb63610a69b0eb7f69a201ba05c4c1a7a2739cf9. Update #3472.
Diffstat (limited to 'freebsd/sys/netpfil')
-rw-r--r--freebsd/sys/netpfil/pf/if_pfsync.c2
-rw-r--r--freebsd/sys/netpfil/pf/pf.c9
-rw-r--r--freebsd/sys/netpfil/pf/pf_if.c21
-rw-r--r--freebsd/sys/netpfil/pf/pf_ioctl.c192
-rw-r--r--freebsd/sys/netpfil/pf/pf_lb.c1
-rw-r--r--freebsd/sys/netpfil/pf/pf_norm.c1
-rw-r--r--freebsd/sys/netpfil/pf/pf_osfp.c1
-rw-r--r--freebsd/sys/netpfil/pf/pf_table.c4
8 files changed, 170 insertions, 61 deletions
diff --git a/freebsd/sys/netpfil/pf/if_pfsync.c b/freebsd/sys/netpfil/pf/if_pfsync.c
index 3ed1b3bb..9b457818 100644
--- a/freebsd/sys/netpfil/pf/if_pfsync.c
+++ b/freebsd/sys/netpfil/pf/if_pfsync.c
@@ -589,6 +589,8 @@ pfsync_input(struct mbuf **mp, int *offp __unused, int proto __unused)
int rv;
uint16_t count;
+ PF_RULES_RLOCK_TRACKER;
+
*mp = NULL;
V_pfsyncstats.pfsyncs_ipackets++;
diff --git a/freebsd/sys/netpfil/pf/pf.c b/freebsd/sys/netpfil/pf/pf.c
index 1aab6f49..3cc4ff11 100644
--- a/freebsd/sys/netpfil/pf/pf.c
+++ b/freebsd/sys/netpfil/pf/pf.c
@@ -371,11 +371,14 @@ u_long pf_hashmask;
u_long pf_srchashmask;
static u_long pf_hashsize;
static u_long pf_srchashsize;
+u_long pf_ioctl_maxcount = 65535;
SYSCTL_ULONG(_net_pf, OID_AUTO, states_hashsize, CTLFLAG_RDTUN,
&pf_hashsize, 0, "Size of pf(4) states hashtable");
SYSCTL_ULONG(_net_pf, OID_AUTO, source_nodes_hashsize, CTLFLAG_RDTUN,
&pf_srchashsize, 0, "Size of pf(4) source nodes hashtable");
+SYSCTL_ULONG(_net_pf, OID_AUTO, request_maxcount, CTLFLAG_RDTUN,
+ &pf_ioctl_maxcount, 0, "Maximum number of tables, addresses, ... in a single ioctl() call");
VNET_DEFINE(void *, pf_swi_cookie);
@@ -5736,8 +5739,7 @@ bad:
/*
* FreeBSD supports cksum offloads for the following drivers.
- * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4),
- * ti(4), txp(4), xl(4)
+ * em(4), fxp(4), lge(4), ndis(4), nge(4), re(4), ti(4), txp(4), xl(4)
*
* CSUM_DATA_VALID | CSUM_PSEUDO_HDR :
* network driver performed cksum including pseudo header, need to verify
@@ -5884,6 +5886,8 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
struct pf_pdesc pd;
int off, dirndx, pqid = 0;
+ PF_RULES_RLOCK_TRACKER;
+
M_ASSERTPKTHDR(m);
if (!V_pf_status.running)
@@ -6271,6 +6275,7 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
struct pf_pdesc pd;
int off, terminal = 0, dirndx, rh_cnt = 0, pqid = 0;
+ PF_RULES_RLOCK_TRACKER;
M_ASSERTPKTHDR(m);
if (!V_pf_status.running)
diff --git a/freebsd/sys/netpfil/pf/pf_if.c b/freebsd/sys/netpfil/pf/pf_if.c
index e224e6a7..2ac76ff2 100644
--- a/freebsd/sys/netpfil/pf/pf_if.c
+++ b/freebsd/sys/netpfil/pf/pf_if.c
@@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$");
#include <sys/eventhandler.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
-#include <sys/rwlock.h>
#include <sys/socket.h>
#include <net/if.h>
@@ -131,9 +130,9 @@ pfi_initialize_vnet(void)
PF_RULES_WUNLOCK();
IFNET_RLOCK();
- TAILQ_FOREACH(ifg, &V_ifg_head, ifg_next)
+ CK_STAILQ_FOREACH(ifg, &V_ifg_head, ifg_next)
pfi_attach_ifgroup(ifg);
- TAILQ_FOREACH(ifp, &V_ifnet, if_link)
+ CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link)
pfi_attach_ifnet(ifp);
IFNET_RUNLOCK();
}
@@ -302,7 +301,7 @@ pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif)
if (rule_kif->pfik_group != NULL)
/* XXXGL: locking? */
- TAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next)
+ CK_STAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next)
if (p->ifgl_group == rule_kif->pfik_group)
return (1);
@@ -468,7 +467,7 @@ pfi_kif_update(struct pfi_kif *kif)
/* again for all groups kif is member of */
if (kif->pfik_ifp != NULL) {
IF_ADDR_RLOCK(kif->pfik_ifp);
- TAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_next)
+ CK_STAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_next)
pfi_kif_update((struct pfi_kif *)
ifgl->ifgl_group->ifg_pf_kif);
IF_ADDR_RUNLOCK(kif->pfik_ifp);
@@ -508,7 +507,7 @@ pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
pfi_instance_add(kif->pfik_ifp, net, flags);
else if (kif->pfik_group != NULL) {
IFNET_RLOCK_NOSLEEP();
- TAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)
+ CK_STAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)
pfi_instance_add(ifgm->ifgm_ifp, net, flags);
IFNET_RUNLOCK_NOSLEEP();
}
@@ -527,7 +526,7 @@ pfi_instance_add(struct ifnet *ifp, int net, int flags)
int net2, af;
IF_ADDR_RLOCK(ifp);
- TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
+ CK_STAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
if (ia->ifa_addr == NULL)
continue;
af = ia->ifa_addr->sa_family;
@@ -670,7 +669,7 @@ pfi_update_status(const char *name, struct pf_status *pfs)
struct pfi_kif *p;
struct pfi_kif_cmp key;
struct ifg_member p_member, *ifgm;
- TAILQ_HEAD(, ifg_member) ifg_members;
+ CK_STAILQ_HEAD(, ifg_member) ifg_members;
int i, j, k;
strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
@@ -685,14 +684,14 @@ pfi_update_status(const char *name, struct pf_status *pfs)
/* build a temporary list for p only */
bzero(&p_member, sizeof(p_member));
p_member.ifgm_ifp = p->pfik_ifp;
- TAILQ_INIT(&ifg_members);
- TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
+ CK_STAILQ_INIT(&ifg_members);
+ CK_STAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
}
if (pfs) {
bzero(pfs->pcounters, sizeof(pfs->pcounters));
bzero(pfs->bcounters, sizeof(pfs->bcounters));
}
- TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
+ CK_STAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
if (ifgm->ifgm_ifp == NULL || ifgm->ifgm_ifp->if_pf_kif == NULL)
continue;
p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
diff --git a/freebsd/sys/netpfil/pf/pf_ioctl.c b/freebsd/sys/netpfil/pf/pf_ioctl.c
index 9be57273..837ad31c 100644
--- a/freebsd/sys/netpfil/pf/pf_ioctl.c
+++ b/freebsd/sys/netpfil/pf/pf_ioctl.c
@@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/proc.h>
-#include <sys/rwlock.h>
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
@@ -204,7 +203,7 @@ VNET_DEFINE(int, pf_vnet_active);
int pf_end_threads;
struct proc *pf_purge_proc;
-struct rwlock pf_rules_lock;
+struct rmlock pf_rules_lock;
struct sx pf_ioctl_lock;
struct sx pf_end_lock;
@@ -218,6 +217,8 @@ pfsync_defer_t *pfsync_defer_ptr = NULL;
/* pflog */
pflog_packet_t *pflog_packet_ptr = NULL;
+extern u_long pf_ioctl_maxcount;
+
static void
pfattach_vnet(void)
{
@@ -995,6 +996,7 @@ static int
pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
{
int error = 0;
+ PF_RULES_RLOCK_TRACKER;
/* XXX keep in sync with switch() below */
if (securelevel_gt(td->td_ucred, 2))
@@ -2542,13 +2544,16 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
- totlen = io->pfrio_size * sizeof(struct pfr_table);
- pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
- M_TEMP, M_WAITOK);
- if (! pfrts) {
+
+ if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
error = ENOMEM;
break;
}
+
+ totlen = io->pfrio_size * sizeof(struct pfr_table);
+ pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
+ M_TEMP, M_WAITOK);
error = copyin(io->pfrio_buffer, pfrts, totlen);
if (error) {
free(pfrts, M_TEMP);
@@ -2571,13 +2576,16 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
- totlen = io->pfrio_size * sizeof(struct pfr_table);
- pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
- M_TEMP, M_WAITOK);
- if (! pfrts) {
+
+ if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) {
error = ENOMEM;
break;
}
+
+ totlen = io->pfrio_size * sizeof(struct pfr_table);
+ pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
+ M_TEMP, M_WAITOK);
error = copyin(io->pfrio_buffer, pfrts, totlen);
if (error) {
free(pfrts, M_TEMP);
@@ -2594,20 +2602,25 @@ DIOCCHANGEADDR_error:
case DIOCRGETTABLES: {
struct pfioc_table *io = (struct pfioc_table *)addr;
struct pfr_table *pfrts;
- size_t totlen;
+ size_t totlen, n;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
break;
}
+ PF_RULES_RLOCK();
+ n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
+ io->pfrio_size = min(io->pfrio_size, n);
+
totlen = io->pfrio_size * sizeof(struct pfr_table);
+
pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
- M_TEMP, M_WAITOK);
- if (! pfrts) {
+ M_TEMP, M_NOWAIT);
+ if (pfrts == NULL) {
error = ENOMEM;
+ PF_RULES_RUNLOCK();
break;
}
- PF_RULES_RLOCK();
error = pfr_get_tables(&io->pfrio_table, pfrts,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_RULES_RUNLOCK();
@@ -2620,20 +2633,24 @@ DIOCCHANGEADDR_error:
case DIOCRGETTSTATS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
struct pfr_tstats *pfrtstats;
- size_t totlen;
+ size_t totlen, n;
if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
error = ENODEV;
break;
}
+ PF_RULES_WLOCK();
+ n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
+ io->pfrio_size = min(io->pfrio_size, n);
+
totlen = io->pfrio_size * sizeof(struct pfr_tstats);
pfrtstats = mallocarray(io->pfrio_size,
- sizeof(struct pfr_tstats), M_TEMP, M_WAITOK);
- if (! pfrtstats) {
+ sizeof(struct pfr_tstats), M_TEMP, M_NOWAIT);
+ if (pfrtstats == NULL) {
error = ENOMEM;
+ PF_RULES_WUNLOCK();
break;
}
- PF_RULES_WLOCK();
error = pfr_get_tstats(&io->pfrio_table, pfrtstats,
&io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_RULES_WUNLOCK();
@@ -2646,25 +2663,31 @@ DIOCCHANGEADDR_error:
case DIOCRCLRTSTATS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
struct pfr_table *pfrts;
- size_t totlen;
+ size_t totlen, n;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
break;
}
+
+ PF_RULES_WLOCK();
+ n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
+ io->pfrio_size = min(io->pfrio_size, n);
+
totlen = io->pfrio_size * sizeof(struct pfr_table);
pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
- M_TEMP, M_WAITOK);
- if (! pfrts) {
+ M_TEMP, M_NOWAIT);
+ if (pfrts == NULL) {
error = ENOMEM;
+ PF_RULES_WUNLOCK();
break;
}
error = copyin(io->pfrio_buffer, pfrts, totlen);
if (error) {
free(pfrts, M_TEMP);
+ PF_RULES_WUNLOCK();
break;
}
- PF_RULES_WLOCK();
error = pfr_clr_tstats(pfrts, io->pfrio_size,
&io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
PF_RULES_WUNLOCK();
@@ -2675,25 +2698,31 @@ DIOCCHANGEADDR_error:
case DIOCRSETTFLAGS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
struct pfr_table *pfrts;
- size_t totlen;
+ size_t totlen, n;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
break;
}
+
+ PF_RULES_WLOCK();
+ n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
+ io->pfrio_size = min(io->pfrio_size, n);
+
totlen = io->pfrio_size * sizeof(struct pfr_table);
pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
- M_TEMP, M_WAITOK);
- if (! pfrts) {
+ M_TEMP, M_NOWAIT);
+ if (pfrts == NULL) {
error = ENOMEM;
+ PF_RULES_WUNLOCK();
break;
}
error = copyin(io->pfrio_buffer, pfrts, totlen);
if (error) {
free(pfrts, M_TEMP);
+ PF_RULES_WUNLOCK();
break;
}
- PF_RULES_WLOCK();
error = pfr_set_tflags(pfrts, io->pfrio_size,
io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
&io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
@@ -2725,9 +2754,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2757,9 +2792,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2789,10 +2830,19 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 || io->pfrio_size2 < 0) {
+ error = EINVAL;
+ break;
+ }
count = max(io->pfrio_size, io->pfrio_size2);
+ if (count > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = count * sizeof(struct pfr_addr);
pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP,
- M_WAITOK);
+ M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2823,9 +2873,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2849,9 +2905,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_astats);
pfrastats = mallocarray(io->pfrio_size,
- sizeof(struct pfr_astats), M_TEMP, M_WAITOK);
+ sizeof(struct pfr_astats), M_TEMP, M_NOWAIT);
if (! pfrastats) {
error = ENOMEM;
break;
@@ -2875,9 +2937,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2907,9 +2975,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2939,9 +3013,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ io->pfrio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2986,9 +3066,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->size < 0 ||
+ io->size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
+ error = EINVAL;
+ break;
+ }
totlen = sizeof(struct pfioc_trans_e) * io->size;
ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! ioes) {
error = ENOMEM;
break;
@@ -3057,9 +3143,15 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->size < 0 ||
+ io->size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
+ error = EINVAL;
+ break;
+ }
totlen = sizeof(struct pfioc_trans_e) * io->size;
ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! ioes) {
error = ENOMEM;
break;
@@ -3128,10 +3220,18 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+
+ if (io->size < 0 ||
+ io->size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
+ error = EINVAL;
+ break;
+ }
+
totlen = sizeof(struct pfioc_trans_e) * io->size;
ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
- M_TEMP, M_WAITOK);
- if (! ioes) {
+ M_TEMP, M_NOWAIT);
+ if (ioes == NULL) {
error = ENOMEM;
break;
}
@@ -3334,13 +3434,21 @@ DIOCCHANGEADDR_error:
break;
}
+ if (io->pfiio_size < 0 ||
+ io->pfiio_size > pf_ioctl_maxcount ||
+ WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) {
+ error = EINVAL;
+ break;
+ }
+
bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
- M_TEMP, M_WAITOK);
- if (! ifstore) {
+ M_TEMP, M_NOWAIT);
+ if (ifstore == NULL) {
error = ENOMEM;
break;
}
+
PF_RULES_RLOCK();
pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
PF_RULES_RUNLOCK();
@@ -3828,7 +3936,7 @@ pf_load(void)
{
int error;
- rw_init(&pf_rules_lock, "pf rulesets");
+ rm_init(&pf_rules_lock, "pf rulesets");
sx_init(&pf_ioctl_lock, "pf ioctl");
sx_init(&pf_end_lock, "pf end thread");
@@ -3901,7 +4009,7 @@ pf_unload(void)
pfi_cleanup();
- rw_destroy(&pf_rules_lock);
+ rm_destroy(&pf_rules_lock);
sx_destroy(&pf_ioctl_lock);
sx_destroy(&pf_end_lock);
}
diff --git a/freebsd/sys/netpfil/pf/pf_lb.c b/freebsd/sys/netpfil/pf/pf_lb.c
index 7ce27a07..1fd02a0b 100644
--- a/freebsd/sys/netpfil/pf/pf_lb.c
+++ b/freebsd/sys/netpfil/pf/pf_lb.c
@@ -48,7 +48,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
-#include <sys/rwlock.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
diff --git a/freebsd/sys/netpfil/pf/pf_norm.c b/freebsd/sys/netpfil/pf/pf_norm.c
index 4f0966ed..61da5e4f 100644
--- a/freebsd/sys/netpfil/pf/pf_norm.c
+++ b/freebsd/sys/netpfil/pf/pf_norm.c
@@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/refcount.h>
-#include <sys/rwlock.h>
#include <sys/socket.h>
#include <net/if.h>
diff --git a/freebsd/sys/netpfil/pf/pf_osfp.c b/freebsd/sys/netpfil/pf/pf_osfp.c
index 1ee16df5..b87d39bd 100644
--- a/freebsd/sys/netpfil/pf/pf_osfp.c
+++ b/freebsd/sys/netpfil/pf/pf_osfp.c
@@ -29,7 +29,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mbuf.h>
-#include <sys/rwlock.h>
#include <sys/socket.h>
#include <netinet/in.h>
diff --git a/freebsd/sys/netpfil/pf/pf_table.c b/freebsd/sys/netpfil/pf/pf_table.c
index 06916204..04a275d9 100644
--- a/freebsd/sys/netpfil/pf/pf_table.c
+++ b/freebsd/sys/netpfil/pf/pf_table.c
@@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/refcount.h>
-#include <sys/rwlock.h>
#include <sys/socket.h>
#include <vm/uma.h>
@@ -179,7 +178,6 @@ static struct pfr_ktable
*pfr_lookup_table(struct pfr_table *);
static void pfr_clean_node_mask(struct pfr_ktable *,
struct pfr_kentryworkq *);
-static int pfr_table_count(struct pfr_table *, int);
static int pfr_skip_table(struct pfr_table *,
struct pfr_ktable *, int);
static struct pfr_kentry
@@ -1690,7 +1688,7 @@ pfr_fix_anchor(char *anchor)
return (0);
}
-static int
+int
pfr_table_count(struct pfr_table *filter, int flags)
{
struct pf_ruleset *rs;