pf: Improve ioctl validation for DIOCIGETIFACES and DIOCXCOMMIT

These ioctls can process a number of items at a time, which puts us at
risk of overflow in mallocarray() and of impossibly large allocations
even if we don't overflow.

There's no obvious limit to the request size for these, so we limit the
requests to something which won't overflow. Change the memory allocation
to M_NOWAIT so excessive requests will fail rather than stall forever.

MFC after:	1 week
This commit is contained in:
Kristof Provost 2018-04-06 19:20:45 +00:00
parent 7083612f28
commit 02214ac854

View File

@ -3143,10 +3143,17 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
error = ENODEV;
break;
}
if (io->size < 0 ||
WOULD_OVERFLOW(io->size, sizeof(struct pfioc_trans_e))) {
error = EINVAL;
break;
}
totlen = sizeof(struct pfioc_trans_e) * io->size;
ioes = mallocarray(io->size, sizeof(struct pfioc_trans_e),
M_TEMP, M_WAITOK);
if (! ioes) {
M_TEMP, M_NOWAIT);
if (ioes == NULL) {
error = ENOMEM;
break;
}
@ -3349,13 +3356,20 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td
break;
}
if (io->pfiio_size < 0 ||
WOULD_OVERFLOW(io->pfiio_size, sizeof(struct pfi_kif))) {
error = EINVAL;
break;
}
bufsiz = io->pfiio_size * sizeof(struct pfi_kif);
ifstore = mallocarray(io->pfiio_size, sizeof(struct pfi_kif),
M_TEMP, M_WAITOK);
if (! ifstore) {
M_TEMP, M_NOWAIT);
if (ifstore == NULL) {
error = ENOMEM;
break;
}
PF_RULES_RLOCK();
pfi_get_ifaces(io->pfiio_name, ifstore, &io->pfiio_size);
PF_RULES_RUNLOCK();