Module Name:    src
Committed By:   jdolecek
Date:           Wed Jun 24 21:54:57 UTC 2020

Modified Files:
        src/sys/external/bsd/ipf/netinet: ip_nat.c

Log Message:
reduce stack usage in ipf_nat_ioctl()

also, in SIOCADNAT, make sure to not leak kernel data


To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/sys/external/bsd/ipf/netinet/ip_nat.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/ipf/netinet/ip_nat.c
diff -u src/sys/external/bsd/ipf/netinet/ip_nat.c:1.21 src/sys/external/bsd/ipf/netinet/ip_nat.c:1.22
--- src/sys/external/bsd/ipf/netinet/ip_nat.c:1.21	Mon Feb  4 07:59:01 2019
+++ src/sys/external/bsd/ipf/netinet/ip_nat.c	Wed Jun 24 21:54:57 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_nat.c,v 1.21 2019/02/04 07:59:01 mrg Exp $	*/
+/*	$NetBSD: ip_nat.c,v 1.22 2020/06/24 21:54:57 jdolecek Exp $	*/
 
 /*
  * Copyright (C) 2012 by Darren Reed.
@@ -112,7 +112,7 @@ extern struct ifnet vpnif;
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_nat.c,v 1.21 2019/02/04 07:59:01 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_nat.c,v 1.22 2020/06/24 21:54:57 jdolecek Exp $");
 #else
 static const char sccsid[] = "@(#)ip_nat.c	1.11 6/5/96 (C) 1995 Darren Reed";
 static const char rcsid[] = "@(#)Id: ip_nat.c,v 1.1.1.2 2012/07/22 13:45:27 darrenr Exp";
@@ -983,7 +983,7 @@ ipf_nat_ioctl(ipf_main_softc_t *softc, v
 	ipf_nat_softc_t *softn = softc->ipf_nat_soft;
 	int error = 0, ret, arg, getlock;
 	ipnat_t *nat, *nt, *n;
-	ipnat_t natd;
+	ipnat_t *natd = NULL;
 	SPL_INT(s);
 
 #if BSD_GE_YEAR(199306) && defined(_KERNEL)
@@ -1017,30 +1017,35 @@ ipf_nat_ioctl(ipf_main_softc_t *softc, v
 
 	if ((cmd == (ioctlcmd_t)SIOCADNAT) || (cmd == (ioctlcmd_t)SIOCRMNAT) ||
 	    (cmd == (ioctlcmd_t)SIOCPURGENAT)) {
+		KMALLOC(natd, ipnat_t *);
+		if (natd == NULL) {
+			error = ENOMEM;
+			goto done;
+		}
 		if (mode & NAT_SYSSPACE) {
-			bcopy(data, (char *)&natd, sizeof(natd));
-			nat = &natd;
+			bcopy(data, natd, sizeof(*natd));
+			nat = natd;
 			error = 0;
 		} else {
-			bzero(&natd, sizeof(natd));
-			error = ipf_inobj(softc, data, NULL, &natd,
+			bzero(natd, sizeof(*natd));
+			error = ipf_inobj(softc, data, NULL, natd,
 					  IPFOBJ_IPNAT);
 			if (error != 0)
 				goto done;
 
-			if (natd.in_size < sizeof(ipnat_t)) {
+			if (natd->in_size < sizeof(ipnat_t)) {
 				error = EINVAL;
 				goto done;
 			}
-			KMALLOCS(nt, ipnat_t *, natd.in_size);
+			KMALLOCS(nt, ipnat_t *, natd->in_size);
 			if (nt == NULL) {
 				IPFERROR(60070);
 				error = ENOMEM;
 				goto done;
 			}
-			bzero(nt, natd.in_size);
+			bzero(nt, natd->in_size);
 			error = ipf_inobjsz(softc, data, nt, IPFOBJ_IPNAT,
-					    natd.in_size);
+					    natd->in_size);
 			if (error)
 				goto done;
 			nat = nt;
@@ -1132,7 +1137,13 @@ ipf_nat_ioctl(ipf_main_softc_t *softc, v
 			IPFERROR(60006);
 			error = EPERM;
 		} else if (n != NULL) {
-			natd.in_flineno = n->in_flineno;
+			KMALLOC(natd, ipnat_t *);
+			if (natd == NULL) {
+				error = ENOMEM;
+				goto done;
+			}
+			bzero(natd, sizeof(*natd));
+			natd->in_flineno = n->in_flineno;
 			(void) ipf_outobj(softc, data, &natd, IPFOBJ_IPNAT);
 			IPFERROR(60007);
 			error = EEXIST;
@@ -1392,6 +1403,8 @@ ipf_nat_ioctl(ipf_main_softc_t *softc, v
 done:
 	if (nat != NULL)
 		ipf_nat_rule_fini(softc, nat);
+	if (natd != NULL)
+		KFREE(natd);
 	if (nt != NULL)
 		KFREES(nt, nt->in_size);
 	return error;

Reply via email to