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. MFC after: 1 week
This commit is contained in:
parent
8129693e78
commit
8748b499c1
@ -89,6 +89,8 @@ __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);
|
||||
|
||||
@ -2530,13 +2532,15 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
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);
|
||||
@ -2559,13 +2563,15 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user