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. Differential Revision: https://reviews.freebsd.org/D15018
This commit is contained in:
parent
9b854eaf9a
commit
205176451d
@ -369,11 +369,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);
|
||||
|
||||
|
@ -89,8 +89,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);
|
||||
|
||||
@ -218,6 +216,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)
|
||||
{
|
||||
@ -2533,7 +2533,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;
|
||||
}
|
||||
@ -2564,7 +2565,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;
|
||||
}
|
||||
@ -2741,6 +2743,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;
|
||||
@ -2778,6 +2781,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;
|
||||
@ -2819,7 +2823,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;
|
||||
}
|
||||
@ -2857,6 +2862,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;
|
||||
@ -2888,6 +2894,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;
|
||||
@ -2919,6 +2926,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;
|
||||
@ -2956,6 +2964,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;
|
||||
@ -2993,6 +3002,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;
|
||||
@ -3045,6 +3055,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;
|
||||
@ -3121,6 +3132,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;
|
||||
@ -3198,6 +3210,7 @@ DIOCCHANGEADDR_error:
|
||||
}
|
||||
|
||||
if (io->size < 0 ||
|
||||
io->size > pf_ioctl_maxcount ||
|
||||
WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
@ -3410,6 +3423,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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user