From owner-svn-src-projects@FreeBSD.ORG  Thu Oct  9 12:37:54 2014
Return-Path: <owner-svn-src-projects@FreeBSD.ORG>
Delivered-To: svn-src-projects@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org
 [IPv6:2001:1900:2254:206a::19:1])
 (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
 (No client certificate requested)
 by hub.freebsd.org (Postfix) with ESMTPS id 10966D4;
 Thu,  9 Oct 2014 12:37:54 +0000 (UTC)
Received: from svn.freebsd.org (svn.freebsd.org
 [IPv6:2001:1900:2254:2068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mx1.freebsd.org (Postfix) with ESMTPS id E5AA2804;
 Thu,  9 Oct 2014 12:37:53 +0000 (UTC)
Received: from svn.freebsd.org ([127.0.1.70])
 by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s99Cbrcq058572;
 Thu, 9 Oct 2014 12:37:53 GMT (envelope-from melifaro@FreeBSD.org)
Received: (from melifaro@localhost)
 by svn.freebsd.org (8.14.9/8.14.9/Submit) id s99CbrFv058571;
 Thu, 9 Oct 2014 12:37:53 GMT (envelope-from melifaro@FreeBSD.org)
Message-Id: <201410091237.s99CbrFv058571@svn.freebsd.org>
X-Authentication-Warning: svn.freebsd.org: melifaro set sender to
 melifaro@FreeBSD.org using -f
From: "Alexander V. Chernikov" <melifaro@FreeBSD.org>
Date: Thu, 9 Oct 2014 12:37:53 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject: svn commit: r272817 - projects/ipfw/sys/netpfil/ipfw
X-SVN-Group: projects
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-projects@freebsd.org
X-Mailman-Version: 2.1.18-1
Precedence: list
List-Id: "SVN commit messages for the src &quot; projects&quot;
 tree" <svn-src-projects.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-projects>, 
 <mailto:svn-src-projects-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-projects/>
List-Post: <mailto:svn-src-projects@freebsd.org>
List-Help: <mailto:svn-src-projects-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-projects>, 
 <mailto:svn-src-projects-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Thu, 09 Oct 2014 12:37:54 -0000

Author: melifaro
Date: Thu Oct  9 12:37:53 2014
New Revision: 272817
URL: https://svnweb.freebsd.org/changeset/base/272817

Log:
  * Wire large user buffer before processing GET request.
  * Fix incorrect size calculation for IP_FW_XGET request.

Modified:
  projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c

Modified: projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c
==============================================================================
--- projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c	Thu Oct  9 12:35:17 2014	(r272816)
+++ projects/ipfw/sys/netpfil/ipfw/ip_fw_sockopt.c	Thu Oct  9 12:37:53 2014	(r272817)
@@ -60,6 +60,8 @@ __FBSDID("$FreeBSD$");
 #include <net/if.h>
 #include <net/route.h>
 #include <net/vnet.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
 
 #include <netinet/in.h>
 #include <netinet/ip_var.h> /* hooks */
@@ -1957,7 +1959,7 @@ dump_static_rules(struct ip_fw_chain *ch
  * Data layout (version 0)(current):
  * Request: [ ipfw_cfg_lheader ] + IPFW_CFG_GET_* flags
  *   size = ipfw_cfg_lheader.size
- * Reply: [ ipfw_rules_lheader 
+ * Reply: [ ipfw_cfg_lheader 
  *   [ ipfw_obj_ctlv(IPFW_TLV_TBL_LIST) ipfw_obj_ntlv x N ] (optional)
  *   [ ipfw_obj_ctlv(IPFW_TLV_RULE_LIST)
  *     ipfw_obj_tlv(IPFW_TLV_RULE_ENT) [ ip_fw_bcounter (optional) ip_fw_rule ]
@@ -1997,7 +1999,7 @@ dump_config(struct ip_fw_chain *chain, i
 	 * STAGE 1: Determine size/count for objects in range.
 	 * Prepare used tables bitmask.
 	 */
-	sz = 0;
+	sz = sizeof(ipfw_cfg_lheader);
 	memset(&da, 0, sizeof(da));
 
 	da.b = 0;
@@ -2550,7 +2552,7 @@ ipfw_flush_sopt_data(struct sockopt_data
 		sd->kavail = sd->valsize - sd->ktotal;
 
 	/* Update sopt buffer */
-	sd->sopt->sopt_valsize = sd->kavail;
+	sd->sopt->sopt_valsize = sd->ktotal;
 	sd->sopt->sopt_val = sd->sopt_val + sd->ktotal;
 
 	return (0);
@@ -2612,7 +2614,7 @@ ipfw_get_sopt_header(struct sockopt_data
 int
 ipfw_ctl3(struct sockopt *sopt)
 {
-	int error;
+	int error, locked;
 	size_t size, valsize;
 	struct ip_fw_chain *chain;
 	char xbuf[256];
@@ -2663,6 +2665,7 @@ ipfw_ctl3(struct sockopt *sopt)
 	 * Fill in sockopt_data structure that may be useful for
 	 * IP_FW3 get requests.
 	 */
+	locked = 0;
 	if (valsize <= sizeof(xbuf)) {
 		/* use on-stack buffer */
 		sdata.kbuf = xbuf;
@@ -2686,6 +2689,14 @@ ipfw_ctl3(struct sockopt *sopt)
 		} else {
 			/* Get request. Allocate sliding window buffer */
 			size = (valsize<CTL3_SMALLBUF) ? valsize:CTL3_SMALLBUF;
+
+			if (size < valsize) {
+				/* We have to wire user buffer */
+				error = vslock(sopt->sopt_val, valsize);
+				if (error != 0)
+					return (error);
+				locked = 1;
+			}
 		}
 
 		sdata.kbuf = malloc(size, M_TEMP, M_WAITOK | M_ZERO);
@@ -2718,6 +2729,9 @@ ipfw_ctl3(struct sockopt *sopt)
 	else
 		ipfw_flush_sopt_data(&sdata);
 
+	if (locked != 0)
+		vsunlock(sdata.sopt_val, valsize);
+
 	/* Restore original pointer and set number of bytes written */
 	sopt->sopt_val = sdata.sopt_val;
 	sopt->sopt_valsize = sdata.ktotal;