Date: Sun, 3 May 2020 16:06:18 +0000 (UTC) From: Kristof Provost <kp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r360607 - stable/12/sys/netpfil/pf Message-ID: <202005031606.043G6Ipw089215@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kp Date: Sun May 3 16:06:17 2020 New Revision: 360607 URL: https://svnweb.freebsd.org/changeset/base/360607 Log: MFC r360344: 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@syzkaller.appspotmail.com Modified: stable/12/sys/netpfil/pf/pf_ioctl.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/netpfil/pf/pf_ioctl.c ============================================================================== --- stable/12/sys/netpfil/pf/pf_ioctl.c Sun May 3 15:39:10 2020 (r360606) +++ stable/12/sys/netpfil/pf/pf_ioctl.c Sun May 3 16:06:17 2020 (r360607) @@ -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();
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005031606.043G6Ipw089215>