From owner-svn-src-projects@freebsd.org Tue Nov 22 10:52:59 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 745A5C4F767 for ; Tue, 22 Nov 2016 10:52:59 +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 344CD172; Tue, 22 Nov 2016 10:52:59 +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 uAMAqw1Z091850; Tue, 22 Nov 2016 10:52:58 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uAMAqwF3091849; Tue, 22 Nov 2016 10:52:58 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201611221052.uAMAqwF3091849@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Tue, 22 Nov 2016 10:52:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r308979 - 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: Tue, 22 Nov 2016 10:52:59 -0000 Author: ae Date: Tue Nov 22 10:52:58 2016 New Revision: 308979 URL: https://svnweb.freebsd.org/changeset/base/308979 Log: Modify key_msg2sp() to reflect changes in struct secpolicy and ipsecrequest. Also add the check that address families are equal in src and dst addresses. Modified: projects/ipsec/sys/netipsec/key.c Modified: projects/ipsec/sys/netipsec/key.c ============================================================================== --- projects/ipsec/sys/netipsec/key.c Tue Nov 22 10:44:04 2016 (r308978) +++ projects/ipsec/sys/netipsec/key.c Tue Nov 22 10:52:58 2016 (r308979) @@ -1166,8 +1166,8 @@ key_newsp(void) /* * create secpolicy structure from sadb_x_policy structure. - * NOTE: `state', `secpolicyindex' in secpolicy structure are not set, - * so must be set properly later. + * NOTE: `state', `secpolicyindex' and 'id' in secpolicy structure + * are not set, so must be set properly later. */ struct secpolicy * key_msg2sp(struct sadb_x_policy *xpl0, size_t len, int *error) @@ -1183,7 +1183,7 @@ key_msg2sp(struct sadb_x_policy *xpl0, s return NULL; } - if ((newsp = KEY_NEWSP()) == NULL) { + if ((newsp = key_newsp()) == NULL) { *error = ENOBUFS; return NULL; } @@ -1191,6 +1191,7 @@ key_msg2sp(struct sadb_x_policy *xpl0, s newsp->spidx.dir = xpl0->sadb_x_policy_dir; newsp->policy = xpl0->sadb_x_policy_type; newsp->priority = xpl0->sadb_x_policy_priority; + newsp->tcount = 0; /* check policy */ switch (xpl0->sadb_x_policy_type) { @@ -1198,20 +1199,19 @@ key_msg2sp(struct sadb_x_policy *xpl0, s case IPSEC_POLICY_NONE: case IPSEC_POLICY_ENTRUST: case IPSEC_POLICY_BYPASS: - newsp->req = NULL; break; case IPSEC_POLICY_IPSEC: { - int tlen; struct sadb_x_ipsecrequest *xisr; - struct ipsecrequest **p_isr = &newsp->req; + struct ipsecrequest *isr; + int tlen; /* validity check */ if (PFKEY_EXTLEN(xpl0) < sizeof(*xpl0)) { ipseclog((LOG_DEBUG, "%s: Invalid msg length.\n", __func__)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EINVAL; return NULL; } @@ -1224,22 +1224,33 @@ key_msg2sp(struct sadb_x_policy *xpl0, s if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) { ipseclog((LOG_DEBUG, "%s: invalid ipsecrequest " "length.\n", __func__)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EINVAL; return NULL; } + if (newsp->tcount >= IPSEC_MAXREQ) { + ipseclog((LOG_DEBUG, + "%s: too many ipsecrequests.\n", + __func__)); + key_freesp(&newsp); + *error = EINVAL; + return (NULL); + } + /* allocate request buffer */ /* NB: data structure is zero'd */ - *p_isr = ipsec_newisr(); - if ((*p_isr) == NULL) { + isr = ipsec_newisr(); + if (isr == NULL) { ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = ENOBUFS; return NULL; } + newsp->req[newsp->tcount++] = isr; + /* set values */ switch (xisr->sadb_x_ipsecrequest_proto) { case IPPROTO_ESP: @@ -1250,11 +1261,12 @@ key_msg2sp(struct sadb_x_policy *xpl0, s ipseclog((LOG_DEBUG, "%s: invalid proto type=%u\n", __func__, xisr->sadb_x_ipsecrequest_proto)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EPROTONOSUPPORT; return NULL; } - (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto; + isr->saidx.proto = + (uint8_t)xisr->sadb_x_ipsecrequest_proto; switch (xisr->sadb_x_ipsecrequest_mode) { case IPSEC_MODE_TRANSPORT: @@ -1265,11 +1277,11 @@ key_msg2sp(struct sadb_x_policy *xpl0, s ipseclog((LOG_DEBUG, "%s: invalid mode=%u\n", __func__, xisr->sadb_x_ipsecrequest_mode)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EINVAL; return NULL; } - (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode; + isr->saidx.mode = xisr->sadb_x_ipsecrequest_mode; switch (xisr->sadb_x_ipsecrequest_level) { case IPSEC_LEVEL_DEFAULT: @@ -1296,16 +1308,16 @@ key_msg2sp(struct sadb_x_policy *xpl0, s if (xisr->sadb_x_ipsecrequest_reqid == 0) { u_int32_t reqid; if ((reqid = key_newreqid()) == 0) { - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = ENOBUFS; return NULL; } - (*p_isr)->saidx.reqid = reqid; + isr->saidx.reqid = reqid; xisr->sadb_x_ipsecrequest_reqid = reqid; } else { /* set it for manual keying. */ - (*p_isr)->saidx.reqid = - xisr->sadb_x_ipsecrequest_reqid; + isr->saidx.reqid = + xisr->sadb_x_ipsecrequest_reqid; } break; @@ -1313,59 +1325,61 @@ key_msg2sp(struct sadb_x_policy *xpl0, s ipseclog((LOG_DEBUG, "%s: invalid level=%u\n", __func__, xisr->sadb_x_ipsecrequest_level)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EINVAL; return NULL; } - (*p_isr)->level = xisr->sadb_x_ipsecrequest_level; + isr->level = xisr->sadb_x_ipsecrequest_level; /* set IP addresses if there */ + /* XXXAE: those are needed only for tunnel mode */ if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) { struct sockaddr *paddr; paddr = (struct sockaddr *)(xisr + 1); - /* validity check */ if (paddr->sa_len - > sizeof((*p_isr)->saidx.src)) { + > sizeof(isr->saidx.src)) { ipseclog((LOG_DEBUG, "%s: invalid " "request address length.\n", __func__)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EINVAL; return NULL; } - bcopy(paddr, &(*p_isr)->saidx.src, - paddr->sa_len); - - paddr = (struct sockaddr *)((caddr_t)paddr - + paddr->sa_len); + bcopy(paddr, &isr->saidx.src, paddr->sa_len); + paddr = (struct sockaddr *)((caddr_t)paddr + + paddr->sa_len); /* validity check */ if (paddr->sa_len - > sizeof((*p_isr)->saidx.dst)) { + > sizeof(isr->saidx.dst)) { ipseclog((LOG_DEBUG, "%s: invalid " "request address length.\n", __func__)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EINVAL; return NULL; } - bcopy(paddr, &(*p_isr)->saidx.dst, - paddr->sa_len); + /* AF family should match */ + if (paddr->sa_family != + isr->saidx.src.sa.sa_family) { + ipseclog((LOG_DEBUG, "%s: address " + "family doesn't match.\n", + __func__)); + key_freesp(&newsp); + *error = EINVAL; + return (NULL); + } + bcopy(paddr, &isr->saidx.dst, paddr->sa_len); } - - (*p_isr)->sp = newsp; - - /* initialization for the next. */ - p_isr = &(*p_isr)->next; tlen -= xisr->sadb_x_ipsecrequest_len; /* validity check */ if (tlen < 0) { ipseclog((LOG_DEBUG, "%s: becoming tlen < 0.\n", __func__)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EINVAL; return NULL; } @@ -1373,19 +1387,26 @@ key_msg2sp(struct sadb_x_policy *xpl0, s xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr + xisr->sadb_x_ipsecrequest_len); } + /* XXXAE: LARVAL SP */ + if (newsp->tcount < 1) { + ipseclog((LOG_DEBUG, "%s: valid IPSEC transforms " + "not found.\n", __func__)); + key_freesp(&newsp); + *error = EINVAL; + return (NULL); + } } break; default: ipseclog((LOG_DEBUG, "%s: invalid policy type.\n", __func__)); - KEY_FREESP(&newsp); + key_freesp(&newsp); *error = EINVAL; return NULL; } *error = 0; - return newsp; + return (newsp); } - static u_int32_t key_newreqid() {