From owner-svn-src-projects@freebsd.org Mon Nov 21 10:36:27 2016 Return-Path: Delivered-To: svn-src-projects@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0B798C4C7A0 for ; Mon, 21 Nov 2016 10:36:27 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B5F90920; Mon, 21 Nov 2016 10:36:26 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uALAaPQj098366; Mon, 21 Nov 2016 10:36:25 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uALAaP0T098364; Mon, 21 Nov 2016 10:36:25 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201611211036.uALAaP0T098364@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Mon, 21 Nov 2016 10:36:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r308917 - projects/ipsec/sys/netipsec X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 Nov 2016 10:36:27 -0000 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);