svn commit: r332496 - stable/11/sys/netpfil/pf
Kristof Provost
kp at FreeBSD.org
Sat Apr 14 00:12:17 UTC 2018
Author: kp
Date: Sat Apr 14 00:12:16 2018
New Revision: 332496
URL: https://svnweb.freebsd.org/changeset/base/332496
Log:
MFC r332142:
pf: Improve ioctl validation
Ensure that multiplications for memory allocations cannot overflow, and
that we'll not try to allocate M_WAITOK for potentially overly large
allocations.
Modified:
stable/11/sys/netpfil/pf/pf_ioctl.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/netpfil/pf/pf_ioctl.c
==============================================================================
--- stable/11/sys/netpfil/pf/pf_ioctl.c Fri Apr 13 22:33:50 2018 (r332495)
+++ stable/11/sys/netpfil/pf/pf_ioctl.c Sat Apr 14 00:12:16 2018 (r332496)
@@ -2733,9 +2733,14 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2765,9 +2770,14 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2797,10 +2807,18 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 || io->pfrio_size2 < 0) {
+ error = EINVAL;
+ break;
+ }
count = max(io->pfrio_size, io->pfrio_size2);
+ if (WOULD_OVERFLOW(count, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = count * sizeof(struct pfr_addr);
pfras = mallocarray(count, sizeof(struct pfr_addr), M_TEMP,
- M_WAITOK);
+ M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2831,9 +2849,14 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2857,9 +2880,14 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_astats))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_astats);
pfrastats = mallocarray(io->pfrio_size,
- sizeof(struct pfr_astats), M_TEMP, M_WAITOK);
+ sizeof(struct pfr_astats), M_TEMP, M_NOWAIT);
if (! pfrastats) {
error = ENOMEM;
break;
@@ -2883,9 +2911,14 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2915,9 +2948,14 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2947,9 +2985,14 @@ DIOCCHANGEADDR_error:
error = ENODEV;
break;
}
+ if (io->pfrio_size < 0 ||
+ WOULD_OVERFLOW(io->pfrio_size, sizeof(struct pfr_addr))) {
+ error = EINVAL;
+ break;
+ }
totlen = io->pfrio_size * sizeof(struct pfr_addr);
pfras = mallocarray(io->pfrio_size, sizeof(struct pfr_addr),
- M_TEMP, M_WAITOK);
+ M_TEMP, M_NOWAIT);
if (! pfras) {
error = ENOMEM;
break;
@@ -2994,9 +3037,14 @@ DIOCCHANGEADDR_error:
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);
+ M_TEMP, M_NOWAIT);
if (! ioes) {
error = ENOMEM;
break;
@@ -3065,9 +3113,14 @@ DIOCCHANGEADDR_error:
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);
+ M_TEMP, M_NOWAIT);
if (! ioes) {
error = ENOMEM;
break;
More information about the svn-src-all
mailing list