svn commit: r357822 - stable/11/sys/netpfil/pf

Glen Barber gjb at FreeBSD.org
Wed Feb 12 14:50:14 UTC 2020


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;


More information about the svn-src-all mailing list