changeset 12655:1759b5b76e53

6945640 ipseckey won't create SA between ipv6 link-local and multicast address; dumps core instead 6949084 pfp_delete_rule() has use-after-free problem
author Vladimir Kotal <Vladimir.Kotal@Sun.COM>
date Mon, 21 Jun 2010 09:53:32 +0200
parents be5c8bdfa777
children 1c0422804a70
files usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipsecconf.c usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipseckey.c
diffstat 2 files changed, 25 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipsecconf.c	Sat Jun 19 07:44:34 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipsecconf.c	Mon Jun 21 09:53:32 2010 +0200
@@ -2653,9 +2653,9 @@
 
 	if (cnt != len) {
 		if (cnt < 0) {
+			warn(gettext("Delete failed: write"));
 			(void) close(sfd);
 			free(msg);
-			warn(gettext("Delete failed: write"));
 			return (-1);
 		} else {
 			(void) close(sfd);
@@ -2668,9 +2668,9 @@
 	cnt = read(sfd, msg, len);
 	if (cnt != len) {
 		if (cnt < 0) {
+			warn(gettext("Delete failed: read"));
 			(void) close(sfd);
 			free(msg);
-			warn(gettext("Delete failed: read"));
 			return (-1);
 		} else {
 			(void) close(sfd);
@@ -2681,9 +2681,9 @@
 	}
 	(void) close(sfd);
 	if (msg->spd_msg_errno != 0) {
-		free(msg);
 		errno = msg->spd_msg_errno;
 		warn(gettext("Delete failed: SPD_FLUSH"));
+		free(msg);
 		return (-1);
 	}
 
--- a/usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipseckey.c	Sat Jun 19 07:44:34 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/ipsecutils/ipseckey.c	Mon Jun 21 09:53:32 2010 +0200
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -1201,7 +1200,7 @@
     boolean_t unspec_src, uint64_t *buffer, int buffer_size, uint32_t spi,
     char *ebuf)
 {
-	boolean_t single_dst;
+	boolean_t last_dst;
 	struct sockaddr_in6 *sin6;
 	struct sadb_msg *msgp;
 	int i, rc;
@@ -1238,10 +1237,6 @@
 	 *	If a source or proxy address explodes, keep unspecified
 	 *	(and mention unspecified).
 	 *
-	 * If dsthp is == dummy.he, then go through the loop once.
-	 * If any other hp is == dummy.he, then you don't have to apply any
-	 * silly rules.
-	 *
 	 * DELETE is different, because you can leave either "src" or "dst"
 	 * blank!  You need to explode if one of them is full, and not assume
 	 * that the other is set.
@@ -1334,8 +1329,12 @@
 		return;
 	}
 
-	single_dst = (dsthp == &dummy.he || dsthp->h_addr_list[1] == NULL);
-
+	/*
+	 * Go through the list of all dst addresses, trying to find matching
+	 * src address for each. If the first address is == dummy.he we will go
+	 * through the loop just once. If any other hp is == dummy.he, then we
+	 * don't have to apply any silly rules.
+	 */
 	for (i = 0; dsthp->h_addr_list[i] != NULL; i++) {
 		if (dsthp == &dummy.he) {
 			/* Just to be sure... */
@@ -1352,6 +1351,8 @@
 			sin6->sin6_port = htons(dstport);
 		}
 
+		last_dst = (dsthp->h_addr_list[i + 1] == NULL);
+
 		/*
 		 * Try and assign src, if there's any ambiguity.
 		 */
@@ -1381,15 +1382,15 @@
 
 				if (first_match == NULL) {
 					/*
-					 * No IPv4 hits.  Is this a single
-					 * dest?
+					 * No IPv4 hits. Is this the last
+					 * destination address in the list ?
 					 */
-					WARN1(ep, ebuf, gettext(
+					ERROR1(ep, ebuf, gettext(
 					    "No IPv4 source address "
 					    "for name %s.\n"), srchp->h_name);
-					if (single_dst) {
-						ERROR(ep, ebuf, gettext(
-						    "Only single destination "
+					if (last_dst) {
+						FATAL(ep, ebuf, gettext(
+						    "No match for destination "
 						    "IP address.\n"));
 					} else {
 						/* Continue, but do I print? */
@@ -1463,16 +1464,16 @@
 				sin6->sin6_port = htons(srcport);
 				if (first_match == NULL) {
 					/*
-					 * No IPv6 hits.  Is this a single
-					 * dest?
+					 * No IPv6 hits. Is this the last
+					 * destination address in the list ?
 					 */
-					WARN1(ep, ebuf, gettext(
+					ERROR1(ep, ebuf, gettext(
 					    "No IPv6 source address of "
 					    "matching scope for name %s.\n"),
 					    srchp->h_name);
-					if (single_dst) {
-						ERROR(ep, ebuf, gettext(
-						    "Only a single IPV6 "
+					if (last_dst) {
+						FATAL(ep, ebuf, gettext(
+						    "No match for IPV6 "
 						    "destination "
 						    "address.\n"));
 					} else {