Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Nov 2016 14:25:25 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r309003 - projects/ipsec/sys/netipsec
Message-ID:  <201611221425.uAMEPPfX078137@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Tue Nov 22 14:25:25 2016
New Revision: 309003
URL: https://svnweb.freebsd.org/changeset/base/309003

Log:
  Modify key_setsaval() to do more accurate checks on SA initialization.

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

Modified: projects/ipsec/sys/netipsec/key.c
==============================================================================
--- projects/ipsec/sys/netipsec/key.c	Tue Nov 22 14:11:18 2016	(r309002)
+++ projects/ipsec/sys/netipsec/key.c	Tue Nov 22 14:25:25 2016	(r309003)
@@ -2905,59 +2905,51 @@ reset:
 }
 
 /*
- * copy SA values from PF_KEY message except *SPI, SEQ, PID, STATE and TYPE*.
- * You must update these if need.
+ * copy SA values from PF_KEY message except *SPI, SEQ, PID and TYPE*.
+ * You must update these if need. Expects only LARVAL SAs.
  * OUT:	0:	success.
  *	!0:	failure.
- *
- * does not modify mbuf.  does not free mbuf on error.
  */
 static int
-key_setsaval(struct secasvar *sav, struct mbuf *m,
-    const struct sadb_msghdr *mhp)
+key_setsaval(struct secasvar *sav, const struct sadb_msghdr *mhp)
 {
-	int error = 0;
+	const struct sadb_sa *sa0;
+	const struct sadb_key *key0;
+	size_t len;
+	int error;
 
-	IPSEC_ASSERT(m != NULL, ("null mbuf"));
 	IPSEC_ASSERT(mhp != NULL, ("null msghdr"));
 	IPSEC_ASSERT(mhp->msg != NULL, ("null msg"));
+	IPSEC_ASSERT(sav->state == SADB_SASTATE_LARVAL,
+	    ("Attempt to update non LARVAL SA"));
 
-	/* initialization */
-	sav->replay = NULL;
-	sav->key_auth = NULL;
-	sav->key_enc = NULL;
-	sav->sched = NULL;
-	sav->schedlen = 0;
-	sav->lft_c = NULL;
-	sav->lft_h = NULL;
-	sav->lft_s = NULL;
-	sav->tdb_xform = NULL;		/* transform */
-	sav->tdb_encalgxform = NULL;	/* encoding algorithm */
-	sav->tdb_authalgxform = NULL;	/* authentication algorithm */
-	sav->tdb_compalgxform = NULL;	/* compression algorithm */
-	/*  Initialize even if NAT-T not compiled in: */
-	sav->natt_type = 0;
-	sav->natt_esp_frag_len = 0;
+	/* XXX rewrite */
+	error = key_setident(sav->sah, mhp);
+	if (error != 0)
+		goto fail;
 
-	/* SA */
-	if (mhp->ext[SADB_EXT_SA] != NULL) {
-		const struct sadb_sa *sa0;
+	error = key_setnatt(sav, mhp);
+	if (error != 0)
+		goto fail;
 
-		sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA];
-		if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) {
+	/* SA */
+	if (!SADB_CHECKHDR(mhp, SADB_EXT_SA)) {
+		if (SADB_CHECKLEN(mhp, SADB_EXT_SA)) {
 			error = EINVAL;
 			goto fail;
 		}
-
+		sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA];
 		sav->alg_auth = sa0->sadb_sa_auth;
 		sav->alg_enc = sa0->sadb_sa_encrypt;
 		sav->flags = sa0->sadb_sa_flags;
 
 		/* replay window */
 		if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) {
-			sav->replay = (struct secreplay *)
-				malloc(sizeof(struct secreplay)+sa0->sadb_sa_replay, M_IPSEC_MISC, M_NOWAIT|M_ZERO);
+			sav->replay = malloc(sizeof(struct secreplay) +
+			    sa0->sadb_sa_replay, M_IPSEC_MISC,
+			    M_NOWAIT | M_ZERO);
 			if (sav->replay == NULL) {
+				PFKEYSTAT_INC(in_nomem);
 				ipseclog((LOG_DEBUG, "%s: No more memory.\n",
 					__func__));
 				error = ENOBUFS;
@@ -2970,18 +2962,14 @@ key_setsaval(struct secasvar *sav, struc
 	}
 
 	/* Authentication keys */
-	if (mhp->ext[SADB_EXT_KEY_AUTH] != NULL) {
-		const struct sadb_key *key0;
-		int len;
-
-		key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_AUTH];
-		len = mhp->extlen[SADB_EXT_KEY_AUTH];
-
-		error = 0;
-		if (len < sizeof(*key0)) {
+	if (!SADB_CHECKHDR(mhp, SADB_EXT_KEY_AUTH)) {
+		if (SADB_CHECKLEN(mhp, SADB_EXT_KEY_AUTH)) {
 			error = EINVAL;
 			goto fail;
 		}
+		error = 0;
+		key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_AUTH];
+		len = mhp->extlen[SADB_EXT_KEY_AUTH];
 		switch (mhp->msg->sadb_msg_satype) {
 		case SADB_SATYPE_AH:
 		case SADB_SATYPE_ESP:
@@ -3001,29 +2989,25 @@ key_setsaval(struct secasvar *sav, struc
 			goto fail;
 		}
 
-		sav->key_auth = (struct seckey *)key_dup_keymsg(key0, len,
-								M_IPSEC_MISC);
+		sav->key_auth = key_dup_keymsg(key0, len, M_IPSEC_MISC);
 		if (sav->key_auth == NULL ) {
 			ipseclog((LOG_DEBUG, "%s: No more memory.\n",
 				  __func__));
+			PFKEYSTAT_INC(in_nomem);
 			error = ENOBUFS;
 			goto fail;
 		}
 	}
 
 	/* Encryption key */
-	if (mhp->ext[SADB_EXT_KEY_ENCRYPT] != NULL) {
-		const struct sadb_key *key0;
-		int len;
-
-		key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_ENCRYPT];
-		len = mhp->extlen[SADB_EXT_KEY_ENCRYPT];
-
-		error = 0;
-		if (len < sizeof(*key0)) {
+	if (!SADB_CHECKHDR(mhp, SADB_EXT_KEY_ENCRYPT)) {
+		if (SADB_CHECKLEN(mhp, SADB_EXT_KEY_ENCRYPT)) {
 			error = EINVAL;
 			goto fail;
 		}
+		error = 0;
+		key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_ENCRYPT];
+		len = mhp->extlen[SADB_EXT_KEY_ENCRYPT];
 		switch (mhp->msg->sadb_msg_satype) {
 		case SADB_SATYPE_ESP:
 			if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
@@ -3031,12 +3015,11 @@ key_setsaval(struct secasvar *sav, struc
 				error = EINVAL;
 				break;
 			}
-			sav->key_enc = (struct seckey *)key_dup_keymsg(key0,
-								       len,
-								       M_IPSEC_MISC);
+			sav->key_enc = key_dup_keymsg(key0, len, M_IPSEC_MISC);
 			if (sav->key_enc == NULL) {
 				ipseclog((LOG_DEBUG, "%s: No more memory.\n",
 					__func__));
+				PFKEYSTAT_INC(in_nomem);
 				error = ENOBUFS;
 				goto fail;
 			}
@@ -3061,87 +3044,80 @@ key_setsaval(struct secasvar *sav, struc
 
 	/* set iv */
 	sav->ivlen = 0;
-
 	switch (mhp->msg->sadb_msg_satype) {
 	case SADB_SATYPE_AH:
+		if (sav->flags & SADB_X_EXT_DERIV) {
+			ipseclog((LOG_DEBUG, "%s: invalid flag (derived) "
+			    "given to AH SA.\n", __func__));
+			error = EINVAL;
+			goto fail;
+		}
+		if (sav->alg_enc != SADB_EALG_NONE) {
+			ipseclog((LOG_DEBUG, "%s: protocol and algorithm "
+			    "mismated.\n", __func__));
+			error = EINVAL;
+			goto fail;
+		}
 		error = xform_init(sav, XF_AH);
 		break;
 	case SADB_SATYPE_ESP:
+		if ((sav->flags & (SADB_X_EXT_OLD | SADB_X_EXT_DERIV)) ==
+		    (SADB_X_EXT_OLD | SADB_X_EXT_DERIV)) {
+			ipseclog((LOG_DEBUG, "%s: invalid flag (derived) "
+			    "given to old-esp.\n", __func__));
+			error = EINVAL;
+			goto fail;
+		}
 		error = xform_init(sav, XF_ESP);
 		break;
 	case SADB_X_SATYPE_IPCOMP:
+		if (sav->alg_auth != SADB_AALG_NONE) {
+			ipseclog((LOG_DEBUG, "%s: protocol and algorithm "
+			    "mismated.\n", __func__));
+			error = EINVAL;
+			goto fail;
+		}
+		if ((sav->flags & SADB_X_EXT_RAWCPI) == 0 &&
+		    ntohl(sav->spi) >= 0x10000) {
+			ipseclog((LOG_DEBUG, "%s: invalid cpi for IPComp.\n",
+			    __func__));
+			error = EINVAL;
+			goto fail;
+		}
 		error = xform_init(sav, XF_IPCOMP);
 		break;
 	case SADB_X_SATYPE_TCPSIGNATURE:
+		if (sav->alg_enc != SADB_EALG_NONE) {
+			ipseclog((LOG_DEBUG, "%s: protocol and algorithm "
+			    "mismated.\n", __func__));
+			error = EINVAL;
+			goto fail;
+		}
 		error = xform_init(sav, XF_TCPSIGNATURE);
 		break;
+	default:
+		ipseclog((LOG_DEBUG, "%s: Invalid satype.\n", __func__));
+		error = EPROTONOSUPPORT;
+		goto fail;
 	}
 	if (error) {
 		ipseclog((LOG_DEBUG, "%s: unable to initialize SA type %u.\n",
-		        __func__, mhp->msg->sadb_msg_satype));
+		    __func__, mhp->msg->sadb_msg_satype));
 		goto fail;
 	}
 
-	/* reset created */
+	/* Initialize lifetime for CURRENT */
+	sav->firstused = 0;
 	sav->created = time_second;
 
-	/* make lifetime for CURRENT */
-	sav->lft_c = malloc(sizeof(struct seclifetime), M_IPSEC_MISC, M_NOWAIT);
-	if (sav->lft_c == NULL) {
-		ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
-		error = ENOBUFS;
-		goto fail;
-	}
-
-	sav->lft_c->allocations = 0;
-	sav->lft_c->bytes = 0;
-	sav->lft_c->addtime = time_second;
-	sav->lft_c->usetime = 0;
-
 	/* lifetimes for HARD and SOFT */
-    {
-	const struct sadb_lifetime *lft0;
-
-	lft0 = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_HARD];
-	if (lft0 != NULL) {
-		if (mhp->extlen[SADB_EXT_LIFETIME_HARD] < sizeof(*lft0)) {
-			error = EINVAL;
-			goto fail;
-		}
-		sav->lft_h = key_dup_lifemsg(lft0, M_IPSEC_MISC);
-		if (sav->lft_h == NULL) {
-			ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__));
-			error = ENOBUFS;
-			goto fail;
-		}
-		/* to be initialize ? */
-	}
-
-	lft0 = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_SOFT];
-	if (lft0 != NULL) {
-		if (mhp->extlen[SADB_EXT_LIFETIME_SOFT] < sizeof(*lft0)) {
-			error = EINVAL;
-			goto fail;
-		}
-		sav->lft_s = key_dup_lifemsg(lft0, M_IPSEC_MISC);
-		if (sav->lft_s == NULL) {
-			ipseclog((LOG_DEBUG, "%s: No more memory.\n",__func__));
-			error = ENOBUFS;
-			goto fail;
-		}
-		/* to be initialize ? */
-	}
-    }
-
-	return 0;
-
- fail:
-	/* initialization */
+	error = key_updatelifetimes(sav, mhp);
+	if (error == 0)
+		return (0);
+fail:
 	key_cleansav(sav);
-
-	return error;
+	return (error);
 }
-
 /*
  * validation with a secasvar entry, and set SADB_SATYPE_MATURE.
  * OUT:	0:	valid



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