Skip site navigation (1)Skip section navigation (2)
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>