Date: Wed, 12 Feb 2020 14:50:13 +0000 (UTC) From: Glen Barber <gjb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r357822 - stable/11/sys/netpfil/pf Message-ID: <202002121450.01CEoDiW012198@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gjb Date: Wed Feb 12 14:50:13 2020 New Revision: 357822 URL: https://svnweb.freebsd.org/changeset/base/357822 Log: MFC r332404 (kp): pf: limit ioctl to a reasonable and tuneable number of elements pf ioctls frequently take a variable number of elements as argument. This can potentially allow users to request very large allocations. These will fail, but even a failing M_NOWAIT might tie up resources and result in concurrent M_WAITOK allocations entering vm_wait and inducing reclamation of caches. Limit these ioctls to what should be a reasonable value, but allow users to tune it should they need to. Sponsored by: Rubicon Communications, LLC (netgate.com) Modified: stable/11/sys/netpfil/pf/pf.c stable/11/sys/netpfil/pf/pf_ioctl.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/netpfil/pf/pf.c ============================================================================== --- stable/11/sys/netpfil/pf/pf.c Wed Feb 12 14:06:02 2020 (r357821) +++ stable/11/sys/netpfil/pf/pf.c Wed Feb 12 14:50:13 2020 (r357822) @@ -363,11 +363,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); Modified: stable/11/sys/netpfil/pf/pf_ioctl.c ============================================================================== --- stable/11/sys/netpfil/pf/pf_ioctl.c Wed Feb 12 14:06:02 2020 (r357821) +++ stable/11/sys/netpfil/pf/pf_ioctl.c Wed Feb 12 14:50:13 2020 (r357822) @@ -86,8 +86,6 @@ __FBSDID("$FreeBSD$"); #include <net/altq/altq.h> #endif -#define PF_TABLES_MAX_REQUEST 65535 /* Maximum tables per request. */ - static struct pf_pool *pf_get_pool(char *, u_int32_t, u_int8_t, u_int32_t, u_int8_t, u_int8_t, u_int8_t); @@ -215,6 +213,8 @@ pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr; /* pflog */ pflog_packet_t *pflog_packet_ptr = NULL; +extern u_long pf_ioctl_maxcount; + static void pfattach_vnet(void) { @@ -2528,7 +2528,8 @@ DIOCCHANGEADDR_error: break; } - if (io->pfrio_size < 0 || io->pfrio_size > PF_TABLES_MAX_REQUEST) { + if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount || + WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) { error = ENOMEM; break; } @@ -2559,7 +2560,8 @@ DIOCCHANGEADDR_error: break; } - if (io->pfrio_size < 0 || io->pfrio_size > PF_TABLES_MAX_REQUEST) { + if (io->pfrio_size < 0 || io->pfrio_size > pf_ioctl_maxcount || + WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_table))) { error = ENOMEM; break; } @@ -2732,6 +2734,7 @@ DIOCCHANGEADDR_error: break; } if (io->pfrio_size < 0 || + io->pfrio_size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { error = EINVAL; break; @@ -2769,6 +2772,7 @@ DIOCCHANGEADDR_error: break; } if (io->pfrio_size < 0 || + io->pfrio_size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { error = EINVAL; break; @@ -2810,7 +2814,8 @@ DIOCCHANGEADDR_error: break; } count = max(io->pfrio_size, io->pfrio_size2); - if (WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) { + if (count > pf_ioctl_maxcount || + WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) { error = EINVAL; break; } @@ -2848,6 +2853,7 @@ DIOCCHANGEADDR_error: break; } if (io->pfrio_size < 0 || + io->pfrio_size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { error = EINVAL; break; @@ -2879,6 +2885,7 @@ DIOCCHANGEADDR_error: break; } if (io->pfrio_size < 0 || + io->pfrio_size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) { error = EINVAL; break; @@ -2910,6 +2917,7 @@ DIOCCHANGEADDR_error: break; } if (io->pfrio_size < 0 || + io->pfrio_size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { error = EINVAL; break; @@ -2947,6 +2955,7 @@ DIOCCHANGEADDR_error: break; } if (io->pfrio_size < 0 || + io->pfrio_size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { error = EINVAL; break; @@ -2984,6 +2993,7 @@ DIOCCHANGEADDR_error: break; } if (io->pfrio_size < 0 || + io->pfrio_size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) { error = EINVAL; break; @@ -3036,6 +3046,7 @@ DIOCCHANGEADDR_error: break; } if (io->size < 0 || + io->size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { error = EINVAL; break; @@ -3112,6 +3123,7 @@ DIOCCHANGEADDR_error: break; } if (io->size < 0 || + io->size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { error = EINVAL; break; @@ -3189,6 +3201,7 @@ DIOCCHANGEADDR_error: } if (io->size < 0 || + io->size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) { error = EINVAL; break; @@ -3407,6 +3420,7 @@ DIOCCHANGEADDR_error: } if (io->pfiio_size < 0 || + io->pfiio_size > pf_ioctl_maxcount || WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) { error = EINVAL; break;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002121450.01CEoDiW012198>