Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Nov 2016 10:36:25 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r308917 - projects/ipsec/sys/netipsec
Message-ID:  <201611211036.uALAaP0T098364@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Mon Nov 21 10:36:25 2016
New Revision: 308917
URL: https://svnweb.freebsd.org/changeset/base/308917

Log:
  Split key_sp2mbuf() function into key_sp2mbuf() and key_sp2msg().
  
  Make key_sp2mbuf() static for private use only in key.c.
  key_sp2msg() takes buffer and its size as arguments. When given buffer
  is not enough to store security policy, function calculates needed size
  and returns it back via sadb_x_policy_len field of struct sadb_x_policy.
  Also reflect changing of struct ipsecrequest.

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

Modified: projects/ipsec/sys/netipsec/key.c
==============================================================================
--- projects/ipsec/sys/netipsec/key.c	Mon Nov 21 10:23:28 2016	(r308916)
+++ projects/ipsec/sys/netipsec/key.c	Mon Nov 21 10:36:25 2016	(r308917)
@@ -464,6 +464,7 @@ static int key_spddump(struct socket *, 
 	const struct sadb_msghdr *);
 static struct mbuf *key_setdumpsp(struct secpolicy *,
 	u_int8_t, u_int32_t, u_int32_t);
+static struct mbuf *key_sp2mbuf(struct secpolicy *);
 static size_t key_getspreqmsglen(struct secpolicy *);
 static int key_spdexpire(struct secpolicy *);
 static struct secashead *key_newsah(struct secasindex *);
@@ -1724,43 +1725,66 @@ key_newreqid()
 /*
  * copy secpolicy struct to sadb_x_policy structure indicated.
  */
-struct mbuf *
-key_sp2msg(struct secpolicy *sp)
+static struct mbuf *
+key_sp2mbuf(struct secpolicy *sp)
 {
-	struct sadb_x_policy *xpl;
-	int tlen;
-	caddr_t p;
 	struct mbuf *m;
-
-	IPSEC_ASSERT(sp != NULL, ("null policy"));
+	size_t tlen;
 
 	tlen = key_getspreqmsglen(sp);
-
 	m = m_get2(tlen, M_NOWAIT, MT_DATA, 0);
 	if (m == NULL)
 		return (NULL);
 	m_align(m, tlen);
 	m->m_len = tlen;
-	xpl = mtod(m, struct sadb_x_policy *);
-	bzero(xpl, tlen);
+	if (key_sp2msg(sp, m->m_data, &tlen) != 0) {
+		m_freem(m);
+		return (NULL);
+	}
+	return (m);
+}
+
+int
+key_sp2msg(struct secpolicy *sp, void *request, size_t *len)
+{
+	struct sadb_x_ipsecrequest *xisr;
+	struct sadb_x_policy *xpl;
+	struct ipsecrequest *isr;
+	size_t xlen, ilen;
+	caddr_t p;
+	int error, i;
+
+	IPSEC_ASSERT(sp != NULL, ("null policy"));
 
-	xpl->sadb_x_policy_len = PFKEY_UNIT64(tlen);
+	xlen = sizeof(*xpl);
+	if (*len < xlen)
+		return (EINVAL);
+
+	error = 0;
+	bzero(request, *len);
+	xpl = (struct sadb_x_policy *)request;
 	xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
 	xpl->sadb_x_policy_type = sp->policy;
 	xpl->sadb_x_policy_dir = sp->spidx.dir;
 	xpl->sadb_x_policy_id = sp->id;
 	xpl->sadb_x_policy_priority = sp->priority;
-	p = (caddr_t)xpl + sizeof(*xpl);
 
 	/* if is the policy for ipsec ? */
 	if (sp->policy == IPSEC_POLICY_IPSEC) {
-		struct sadb_x_ipsecrequest *xisr;
-		struct ipsecrequest *isr;
-
-		for (isr = sp->req; isr != NULL; isr = isr->next) {
-
+		p = (caddr_t)xpl + sizeof(*xpl);
+		for (i = 0; i < sp->tcount; i++) {
+			isr = sp->req[i];
+			ilen = PFKEY_ALIGN8(sizeof(*xisr) +
+			    isr->saidx.src.sa.sa_len +
+			    isr->saidx.dst.sa.sa_len);
+			xlen += ilen;
+			if (xlen > *len) {
+				error = ENOBUFS;
+				/* Calculate needed size */
+				continue;
+			}
 			xisr = (struct sadb_x_ipsecrequest *)p;
-
+			xisr->sadb_x_ipsecrequest_len = ilen;
 			xisr->sadb_x_ipsecrequest_proto = isr->saidx.proto;
 			xisr->sadb_x_ipsecrequest_mode = isr->saidx.mode;
 			xisr->sadb_x_ipsecrequest_level = isr->level;
@@ -1770,16 +1794,15 @@ key_sp2msg(struct secpolicy *sp)
 			bcopy(&isr->saidx.src, p, isr->saidx.src.sa.sa_len);
 			p += isr->saidx.src.sa.sa_len;
 			bcopy(&isr->saidx.dst, p, isr->saidx.dst.sa.sa_len);
-			p += isr->saidx.src.sa.sa_len;
-
-			xisr->sadb_x_ipsecrequest_len =
-				PFKEY_ALIGN8(sizeof(*xisr)
-					+ isr->saidx.src.sa.sa_len
-					+ isr->saidx.dst.sa.sa_len);
+			p += isr->saidx.dst.sa.sa_len;
 		}
 	}
-
-	return m;
+	xpl->sadb_x_policy_len = PFKEY_UNIT64(xlen);
+	if (error == 0)
+		*len = xlen;
+	else
+		*len = sizeof(*xpl);
+	return (error);
 }
 
 /* m will not be freed nor modified */

Modified: projects/ipsec/sys/netipsec/key.h
==============================================================================
--- projects/ipsec/sys/netipsec/key.h	Mon Nov 21 10:23:28 2016	(r308916)
+++ projects/ipsec/sys/netipsec/key.h	Mon Nov 21 10:36:25 2016	(r308917)
@@ -99,7 +99,9 @@ extern int key_checkrequest(struct ipsec
     const struct secasindex *);
 extern struct secpolicy *key_msg2sp(struct sadb_x_policy *,
     size_t, int *);
-extern struct mbuf *key_sp2msg(struct secpolicy *);
+
+int key_sp2msg(struct secpolicy *, void *request, size_t *len);
+
 extern int key_ismyaddr(struct sockaddr *);
 extern int key_spdacquire(struct secpolicy *);
 extern u_long key_random(void);



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