Module Name:    src
Committed By:   ozaki-r
Date:           Tue Jul 11 04:55:39 UTC 2017

Modified Files:
        src/sys/netipsec: key.c

Log Message:
Let key_getsavbyspi take a reference of a returning sav


To generate a diff of this commit:
cvs rdiff -u -r1.173 -r1.174 src/sys/netipsec/key.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/netipsec/key.c
diff -u src/sys/netipsec/key.c:1.173 src/sys/netipsec/key.c:1.174
--- src/sys/netipsec/key.c:1.173	Tue Jul 11 04:50:59 2017
+++ src/sys/netipsec/key.c	Tue Jul 11 04:55:39 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: key.c,v 1.173 2017/07/11 04:50:59 ozaki-r Exp $	*/
+/*	$NetBSD: key.c,v 1.174 2017/07/11 04:55:39 ozaki-r Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $	*/
 /*	$KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.173 2017/07/11 04:50:59 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.174 2017/07/11 04:55:39 ozaki-r Exp $");
 
 /*
  * This code is referd to RFC 2367
@@ -427,7 +427,7 @@ static struct secasvar *key_newsav(struc
 	key_newsav(m, sadb, e, __func__, __LINE__)
 static void key_delsav (struct secasvar *);
 static struct secashead *key_getsah(const struct secasindex *, int);
-static struct secasvar *key_checkspidup (const struct secasindex *, u_int32_t);
+static bool key_checkspidup(const struct secasindex *, u_int32_t);
 static struct secasvar *key_getsavbyspi (struct secashead *, u_int32_t);
 static int key_setsaval (struct secasvar *, struct mbuf *,
 	const struct sadb_msghdr *);
@@ -3033,7 +3033,7 @@ key_getsah(const struct secasindex *said
  *	NULL	: not found
  *	others	: found, pointer to a SA.
  */
-static struct secasvar *
+static bool
 key_checkspidup(const struct secasindex *saidx, u_int32_t spi)
 {
 	struct secashead *sah;
@@ -3042,7 +3042,7 @@ key_checkspidup(const struct secasindex 
 	/* check address family */
 	if (saidx->src.sa.sa_family != saidx->dst.sa.sa_family) {
 		IPSECLOG(LOG_DEBUG, "address family mismatched.\n");
-		return NULL;
+		return false;
 	}
 
 	/* check all SAD */
@@ -3050,11 +3050,13 @@ key_checkspidup(const struct secasindex 
 		if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst))
 			continue;
 		sav = key_getsavbyspi(sah, spi);
-		if (sav != NULL)
-			return sav;
+		if (sav != NULL) {
+			KEY_FREESAV(&sav);
+			return true;
+		}
 	}
 
-	return NULL;
+	return false;
 }
 
 /*
@@ -3081,8 +3083,10 @@ key_getsavbyspi(struct secashead *sah, u
 				continue;
 			}
 
-			if (sav->spi == spi)
+			if (sav->spi == spi) {
+				SA_ADDREF(sav);
 				return sav;
+			}
 		}
 	}
 
@@ -4995,7 +4999,7 @@ key_do_getnewspi(const struct sadb_spira
 	}
 
 	if (spmin == spmax) {
-		if (key_checkspidup(saidx, htonl(spmin)) != NULL) {
+		if (key_checkspidup(saidx, htonl(spmin))) {
 			IPSECLOG(LOG_DEBUG, "SPI %u exists already.\n", spmin);
 			return 0;
 		}
@@ -5013,7 +5017,7 @@ key_do_getnewspi(const struct sadb_spira
 			/* generate pseudo-random SPI value ranged. */
 			newspi = spmin + (key_random() % (spmax - spmin + 1));
 
-			if (key_checkspidup(saidx, htonl(newspi)) == NULL)
+			if (!key_checkspidup(saidx, htonl(newspi)))
 				break;
 		}
 
@@ -5265,20 +5269,23 @@ key_api_update(struct socket *so, struct
 	if (sav->sah->saidx.proto != proto) {
 		IPSECLOG(LOG_DEBUG, "protocol mismatched (DB=%u param=%u)\n",
 		    sav->sah->saidx.proto, proto);
-		return key_senderror(so, m, EINVAL);
+		error = EINVAL;
+		goto error;
 	}
 #ifdef IPSEC_DOSEQCHECK
 	if (sav->spi != sa0->sadb_sa_spi) {
 		IPSECLOG(LOG_DEBUG, "SPI mismatched (DB:%u param:%u)\n",
 		    (u_int32_t)ntohl(sav->spi),
 		    (u_int32_t)ntohl(sa0->sadb_sa_spi));
-		return key_senderror(so, m, EINVAL);
+		error = EINVAL;
+		goto error;
 	}
 #endif
 	if (sav->pid != mhp->msg->sadb_msg_pid) {
 		IPSECLOG(LOG_DEBUG, "pid mismatched (DB:%u param:%u)\n",
 		    sav->pid, mhp->msg->sadb_msg_pid);
-		return key_senderror(so, m, EINVAL);
+		error = EINVAL;
+		goto error;
 	}
 
 	/*
@@ -5297,19 +5304,19 @@ key_api_update(struct socket *so, struct
 	error = key_setsaval(newsav, m, mhp);
 	if (error) {
 		key_delsav(newsav);
-		return key_senderror(so, m, error);
+		goto error;
 	}
 
 	error = key_handle_natt_info(newsav, mhp);
 	if (error != 0) {
 		key_delsav(newsav);
-		return key_senderror(so, m, error);
+		goto error;
 	}
 
 	error = key_init_xform(newsav);
 	if (error != 0) {
 		key_delsav(newsav);
-		return key_senderror(so, m, error);
+		goto error;
 	}
 
 	/* add to satree */
@@ -5320,6 +5327,7 @@ key_api_update(struct socket *so, struct
 
 	key_sa_chgstate(sav, SADB_SASTATE_DEAD);
 	KEY_FREESAV(&sav);
+	KEY_FREESAV(&sav);
 
     {
 	struct mbuf *n;
@@ -5334,6 +5342,9 @@ key_api_update(struct socket *so, struct
 	m_freem(m);
 	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
     }
+error:
+	KEY_FREESAV(&sav);
+	return key_senderror(so, m, error);
 }
 
 /*
@@ -5465,12 +5476,19 @@ key_api_add(struct socket *so, struct mb
 		return key_senderror(so, m, error);
 	}
 
-	/* create new SA entry. */
+    {
+	struct secasvar *sav;
+
 	/* We can create new SA only if SPI is differenct. */
-	if (key_getsavbyspi(newsah, sa0->sadb_sa_spi)) {
+	sav = key_getsavbyspi(newsah, sa0->sadb_sa_spi);
+	if (sav != NULL) {
+		KEY_FREESAV(&sav);
 		IPSECLOG(LOG_DEBUG, "SA already exists.\n");
 		return key_senderror(so, m, EEXIST);
 	}
+    }
+
+	/* create new SA entry. */
 	newsav = KEY_NEWSAV(m, mhp, &error);
 	if (newsav == NULL) {
 		return key_senderror(so, m, error);
@@ -5711,6 +5729,7 @@ key_api_delete(struct socket *so, struct
 
 	key_sa_chgstate(sav, SADB_SASTATE_DEAD);
 	KEY_FREESAV(&sav);
+	KEY_FREESAV(&sav);
 
     {
 	struct mbuf *n;
@@ -5868,6 +5887,7 @@ key_api_get(struct socket *so, struct mb
 	/* map proto to satype */
 	satype = key_proto2satype(sah->saidx.proto);
 	if (satype == 0) {
+		KEY_FREESAV(&sav);
 		IPSECLOG(LOG_DEBUG, "there was invalid proto in SAD.\n");
 		return key_senderror(so, m, EINVAL);
 	}
@@ -5875,6 +5895,7 @@ key_api_get(struct socket *so, struct mb
 	/* create new sadb_msg to reply. */
 	n = key_setdumpsa(sav, SADB_GET, satype, mhp->msg->sadb_msg_seq,
 	    mhp->msg->sadb_msg_pid);
+	KEY_FREESAV(&sav);
 	if (!n)
 		return key_senderror(so, m, ENOBUFS);
 

Reply via email to