svn commit: r360344 - head/sys/netpfil/pf
Kristof Provost
kp at FreeBSD.org
Sun Apr 26 16:16:40 UTC 2020
Author: kp
Date: Sun Apr 26 16:16:39 2020
New Revision: 360344
URL: https://svnweb.freebsd.org/changeset/base/360344
Log:
pf: Improve input validation
If we pass an anchor name which doesn't exist pfr_table_count() returns
-1, which leads to an overflow in mallocarray() and thus a panic.
Explicitly check that pfr_table_count() does not return an error.
Reported-by: syzbot+bd09d55d897d63d5f4f4 at syzkaller.appspotmail.com
Reviewed by: melifaro
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D24539
Modified:
head/sys/netpfil/pf/pf_ioctl.c
Modified: head/sys/netpfil/pf/pf_ioctl.c
==============================================================================
--- head/sys/netpfil/pf/pf_ioctl.c Sun Apr 26 16:13:51 2020 (r360343)
+++ head/sys/netpfil/pf/pf_ioctl.c Sun Apr 26 16:16:39 2020 (r360344)
@@ -3008,7 +3008,8 @@ DIOCCHANGEADDR_error:
case DIOCRGETTABLES: {
struct pfioc_table *io = (struct pfioc_table *)addr;
struct pfr_table *pfrts;
- size_t totlen, n;
+ size_t totlen;
+ int n;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
@@ -3016,6 +3017,11 @@ DIOCCHANGEADDR_error:
}
PF_RULES_RLOCK();
n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
+ if (n < 0) {
+ PF_RULES_RUNLOCK();
+ error = EINVAL;
+ break;
+ }
io->pfrio_size = min(io->pfrio_size, n);
totlen = io->pfrio_size * sizeof(struct pfr_table);
@@ -3039,7 +3045,8 @@ DIOCCHANGEADDR_error:
case DIOCRGETTSTATS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
struct pfr_tstats *pfrtstats;
- size_t totlen, n;
+ size_t totlen;
+ int n;
if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
error = ENODEV;
@@ -3047,6 +3054,11 @@ DIOCCHANGEADDR_error:
}
PF_RULES_WLOCK();
n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
+ if (n < 0) {
+ PF_RULES_WUNLOCK();
+ error = EINVAL;
+ break;
+ }
io->pfrio_size = min(io->pfrio_size, n);
totlen = io->pfrio_size * sizeof(struct pfr_tstats);
@@ -3069,7 +3081,8 @@ DIOCCHANGEADDR_error:
case DIOCRCLRTSTATS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
struct pfr_table *pfrts;
- size_t totlen, n;
+ size_t totlen;
+ int n;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
@@ -3078,6 +3091,11 @@ DIOCCHANGEADDR_error:
PF_RULES_WLOCK();
n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
+ if (n < 0) {
+ PF_RULES_WUNLOCK();
+ error = EINVAL;
+ break;
+ }
io->pfrio_size = min(io->pfrio_size, n);
totlen = io->pfrio_size * sizeof(struct pfr_table);
@@ -3104,7 +3122,8 @@ DIOCCHANGEADDR_error:
case DIOCRSETTFLAGS: {
struct pfioc_table *io = (struct pfioc_table *)addr;
struct pfr_table *pfrts;
- size_t totlen, n;
+ size_t totlen;
+ int n;
if (io->pfrio_esize != sizeof(struct pfr_table)) {
error = ENODEV;
@@ -3113,6 +3132,12 @@ DIOCCHANGEADDR_error:
PF_RULES_RLOCK();
n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
+ if (n < 0) {
+ PF_RULES_RUNLOCK();
+ error = EINVAL;
+ break;
+ }
+
io->pfrio_size = min(io->pfrio_size, n);
PF_RULES_RUNLOCK();
More information about the svn-src-all
mailing list