Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Nov 2016 08:06:17 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r309036 - projects/ipsec/sys/netipsec
Message-ID:  <201611230806.uAN86HDb012759@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Nov 23 08:06:17 2016
New Revision: 309036
URL: https://svnweb.freebsd.org/changeset/base/309036

Log:
  Update key_delete() to reflect changes in SADB and use more accurate
  sanity checks.

Modified:
  projects/ipsec/sys/netipsec/key.c

Modified: projects/ipsec/sys/netipsec/key.c
==============================================================================
--- projects/ipsec/sys/netipsec/key.c	Wed Nov 23 07:57:52 2016	(r309035)
+++ projects/ipsec/sys/netipsec/key.c	Wed Nov 23 08:06:17 2016	(r309036)
@@ -5221,12 +5221,11 @@ key_getmsgbuf_x1(struct mbuf *m, const s
 static int
 key_delete(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
 {
-	struct sadb_sa *sa0;
-	struct sadb_address *src0, *dst0;
 	struct secasindex saidx;
-	struct secashead *sah;
-	struct secasvar *sav = NULL;
-	u_int16_t proto;
+	struct sadb_address *src0, *dst0;
+	struct secasvar *sav;
+	struct sadb_sa *sa0;
+	uint8_t proto;
 
 	IPSEC_ASSERT(so != NULL, ("null socket"));
 	IPSEC_ASSERT(m != NULL, ("null mbuf"));
@@ -5236,45 +5235,28 @@ key_delete(struct socket *so, struct mbu
 	/* map satype to proto */
 	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
 		ipseclog((LOG_DEBUG, "%s: invalid satype is passed.\n",
-			__func__));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) {
-		ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n",
-			__func__));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
-		ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n",
-			__func__));
+		    __func__));
 		return key_senderror(so, m, EINVAL);
 	}
 
-	if (mhp->ext[SADB_EXT_SA] == NULL) {
-		/*
-		 * Caller wants us to delete all non-LARVAL SAs
-		 * that match the src/dst.  This is used during
-		 * IKE INITIAL-CONTACT.
-		 */
-		ipseclog((LOG_DEBUG, "%s: doing delete all.\n", __func__));
-		return key_delete_all(so, m, mhp, proto);
-	} else if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa)) {
+	if (SADB_CHECKHDR(mhp, SADB_EXT_ADDRESS_SRC) ||
+	    SADB_CHECKHDR(mhp, SADB_EXT_ADDRESS_DST) ||
+	    SADB_CHECKLEN(mhp, SADB_EXT_ADDRESS_SRC) ||
+	    SADB_CHECKLEN(mhp, SADB_EXT_ADDRESS_DST)) {
 		ipseclog((LOG_DEBUG, "%s: invalid message is passed.\n",
-			__func__));
+		    __func__));
 		return key_senderror(so, m, EINVAL);
 	}
 
-	sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA];
 	src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
 	dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
 
-	/* XXX boundary check against sa_len */
+	if (key_checksockaddrs((struct sockaddr *)(src0 + 1),
+	    (struct sockaddr *)(dst0 + 1)) != 0) {
+		ipseclog((LOG_DEBUG, "%s: invalid sockaddr.\n", __func__));
+		return (key_senderror(so, m, EINVAL));
+	}
 	KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
-
 	/*
 	 * Make sure the port numbers are zero.
 	 * In case of NAT-T we will update them later if needed.
@@ -5282,57 +5264,39 @@ key_delete(struct socket *so, struct mbu
 	KEY_PORTTOSADDR(&saidx.src, 0);
 	KEY_PORTTOSADDR(&saidx.dst, 0);
 
-#ifdef IPSEC_NAT_T
-	/*
-	 * Handle NAT-T info if present.
-	 */
-	if (mhp->ext[SADB_X_EXT_NAT_T_SPORT] != NULL &&
-	    mhp->ext[SADB_X_EXT_NAT_T_DPORT] != NULL) {
-		struct sadb_x_nat_t_port *sport, *dport;
-
-		if (mhp->extlen[SADB_X_EXT_NAT_T_SPORT] < sizeof(*sport) ||
-		    mhp->extlen[SADB_X_EXT_NAT_T_DPORT] < sizeof(*dport)) {
-			ipseclog((LOG_DEBUG, "%s: invalid message.\n",
-			    __func__));
-			return key_senderror(so, m, EINVAL);
-		}
-
-		sport = (struct sadb_x_nat_t_port *)
-		    mhp->ext[SADB_X_EXT_NAT_T_SPORT];
-		dport = (struct sadb_x_nat_t_port *)
-		    mhp->ext[SADB_X_EXT_NAT_T_DPORT];
-
-		if (sport)
-			KEY_PORTTOSADDR(&saidx.src,
-			    sport->sadb_x_nat_t_port_port);
-		if (dport)
-			KEY_PORTTOSADDR(&saidx.dst,
-			    dport->sadb_x_nat_t_port_port);
-	}
-#endif
-
-	/* get a SA header */
-	SAHTREE_LOCK();
-	LIST_FOREACH(sah, &V_sahtree, chain) {
-		if (sah->state == SADB_SASTATE_DEAD)
-			continue;
-		if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
-			continue;
-
-		/* get a SA with SPI. */
-		sav = key_getsavbyspi(sah, sa0->sadb_sa_spi);
-		if (sav)
-			break;
+	if (SADB_CHECKHDR(mhp, SADB_EXT_SA)) {
+		/*
+		 * Caller wants us to delete all non-LARVAL SAs
+		 * that match the src/dst.  This is used during
+		 * IKE INITIAL-CONTACT.
+		 * XXXAE: this looks like some extension to RFC2367.
+		 */
+		ipseclog((LOG_DEBUG, "%s: doing delete all.\n", __func__));
+		return (key_delete_all(so, m, mhp, &saidx));
 	}
-	if (sah == NULL) {
-		SAHTREE_UNLOCK();
-		ipseclog((LOG_DEBUG, "%s: no SA found.\n", __func__));
-		return key_senderror(so, m, ENOENT);
+	if (SADB_CHECKLEN(mhp, SADB_EXT_SA)) {
+		ipseclog((LOG_DEBUG,
+		    "%s: invalid message: wrong header size.\n", __func__));
+		return (key_senderror(so, m, EINVAL));
 	}
-
-	key_sa_chgstate(sav, SADB_SASTATE_DEAD);
-	KEY_FREESAV(&sav);
-	SAHTREE_UNLOCK();
+	sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA];
+	sav = key_getsavbyspi(sa0->sadb_sa_spi);
+	if (sav == NULL) {
+		ipseclog((LOG_DEBUG, "%s: no SA found for SPI %u.\n",
+		    __func__, ntohl(sa0->sadb_sa_spi)));
+		return (key_senderror(so, m, ESRCH));
+	}
+	if (key_cmpsaidx(&sav->sah->saidx, &saidx, CMP_HEAD) == 0) {
+		ipseclog((LOG_DEBUG, "%s: saidx mismatched for SPI %u.\n",
+		    __func__, ntohl(sav->spi)));
+		key_freesav(&sav);
+		return (key_senderror(so, m, ESRCH));
+	}
+	KEYDBG(KEY_STAMP,
+	    printf("%s: SA(%p)\n", __func__, sav));
+	KEYDBG(KEY_DATA, kdebug_secasv(sav));
+	key_unlinksav(sav);
+	key_freesav(&sav);
 
     {
 	struct mbuf *n;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201611230806.uAN86HDb012759>