MFC r332101:

pf: Improve ioctl validation for DIOCRADDTABLES and DIOCRDELTABLES

The DIOCRADDTABLES and DIOCRDELTABLES ioctls can process a number of
tables at a time, and as such try to allocate <number of tables> *
sizeof(struct pfr_table). This multiplication can overflow. Thanks to
mallocarray() this is not exploitable, but an overflow does panic the
system.

Arbitrarily limit this to 65535 tables. pfctl only ever processes one
table at a time, so it presents no issues there.
This commit is contained in:
Kristof Provost 2018-04-13 19:23:06 +00:00
parent 44e54b2a0c
commit 02be584fa3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/stable/10/; revision=332487

View File

@ -83,6 +83,8 @@ __FBSDID("$FreeBSD$");
#include <altq/altq.h>
#endif
#define PF_TABLES_MAX_REQUEST 65535 /* Maximum tables per request. */
static int pfattach(void);
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);
@ -2513,13 +2515,15 @@ 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_TABLES_MAX_REQUEST) {
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);
@ -2542,13 +2546,15 @@ 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_TABLES_MAX_REQUEST) {
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);