From owner-svn-src-head@freebsd.org Fri Apr 6 19:36:36 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 39A9BFA1CF8; Fri, 6 Apr 2018 19:36:36 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id CF54471F6D; Fri, 6 Apr 2018 19:36:35 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C5FBA16373; Fri, 6 Apr 2018 19:36:35 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w36JaZ8v033105; Fri, 6 Apr 2018 19:36:35 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w36JaZVq033104; Fri, 6 Apr 2018 19:36:35 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201804061936.w36JaZVq033104@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Fri, 6 Apr 2018 19:36:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r332142 - head/sys/netpfil/pf X-SVN-Group: head X-SVN-Commit-Author: kp X-SVN-Commit-Paths: head/sys/netpfil/pf X-SVN-Commit-Revision: 332142 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 06 Apr 2018 19:36:36 -0000 Author: kp Date: Fri Apr 6 19:36:35 2018 New Revision: 332142 URL: https://svnweb.freebsd.org/changeset/base/332142 Log: 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. MFC after: 1 week Modified: head/sys/netpfil/pf/pf_ioctl.c Modified: head/sys/netpfil/pf/pf_ioctl.c ============================================================================== --- head/sys/netpfil/pf/pf_ioctl.c Fri Apr 6 19:34:21 2018 (r332141) +++ head/sys/netpfil/pf/pf_ioctl.c Fri Apr 6 19:36:35 2018 (r332142) @@ -2740,9 +2740,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; @@ -2772,9 +2777,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; @@ -2804,10 +2814,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; @@ -2838,9 +2856,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; @@ -2864,9 +2887,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; @@ -2890,9 +2918,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; @@ -2922,9 +2955,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; @@ -2954,9 +2992,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; @@ -3001,9 +3044,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; @@ -3072,9 +3120,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;