Fri Dec 1 06:34:14 2017 UTC ()
Don't touch an SP without a reference to it


(ozaki-r)
diff -r1.245 -r1.246 src/sys/netipsec/key.c

cvs diff -r1.245 -r1.246 src/sys/netipsec/key.c (expand / switch to unified diff)

--- src/sys/netipsec/key.c 2017/11/30 02:45:12 1.245
+++ src/sys/netipsec/key.c 2017/12/01 06:34:14 1.246
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: key.c,v 1.245 2017/11/30 02:45:12 ozaki-r Exp $ */ 1/* $NetBSD: key.c,v 1.246 2017/12/01 06:34:14 ozaki-r Exp $ */
2/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ 2/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
3/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */ 3/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
4 4
5/* 5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE. 31 * SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.245 2017/11/30 02:45:12 ozaki-r Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.246 2017/12/01 06:34:14 ozaki-r Exp $");
36 36
37/* 37/*
38 * This code is referred to RFC 2367 38 * This code is referred to RFC 2367
39 */ 39 */
40 40
41#if defined(_KERNEL_OPT) 41#if defined(_KERNEL_OPT)
42#include "opt_inet.h" 42#include "opt_inet.h"
43#include "opt_ipsec.h" 43#include "opt_ipsec.h"
44#include "opt_gateway.h" 44#include "opt_gateway.h"
45#include "opt_net_mpsafe.h" 45#include "opt_net_mpsafe.h"
46#endif 46#endif
47 47
48#include <sys/types.h> 48#include <sys/types.h>
@@ -2102,26 +2102,27 @@ key_gather_mbuf(struct mbuf *m, const st @@ -2102,26 +2102,27 @@ key_gather_mbuf(struct mbuf *m, const st
2102 * m will always be freed. 2102 * m will always be freed.
2103 */ 2103 */
2104static int 2104static int
2105key_api_spdadd(struct socket *so, struct mbuf *m, 2105key_api_spdadd(struct socket *so, struct mbuf *m,
2106 const struct sadb_msghdr *mhp) 2106 const struct sadb_msghdr *mhp)
2107{ 2107{
2108 const struct sockaddr *src, *dst; 2108 const struct sockaddr *src, *dst;
2109 const struct sadb_x_policy *xpl0; 2109 const struct sadb_x_policy *xpl0;
2110 struct sadb_x_policy *xpl; 2110 struct sadb_x_policy *xpl;
2111 const struct sadb_lifetime *lft = NULL; 2111 const struct sadb_lifetime *lft = NULL;
2112 struct secpolicyindex spidx; 2112 struct secpolicyindex spidx;
2113 struct secpolicy *newsp; 2113 struct secpolicy *newsp;
2114 int error; 2114 int error;
 2115 uint32_t sadb_x_policy_id;
2115 2116
2116 if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL || 2117 if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
2117 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL || 2118 mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
2118 mhp->ext[SADB_X_EXT_POLICY] == NULL) { 2119 mhp->ext[SADB_X_EXT_POLICY] == NULL) {
2119 IPSECLOG(LOG_DEBUG, "invalid message is passed.\n"); 2120 IPSECLOG(LOG_DEBUG, "invalid message is passed.\n");
2120 return key_senderror(so, m, EINVAL); 2121 return key_senderror(so, m, EINVAL);
2121 } 2122 }
2122 if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) || 2123 if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
2123 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) || 2124 mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) ||
2124 mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) { 2125 mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
2125 IPSECLOG(LOG_DEBUG, "invalid message is passed.\n"); 2126 IPSECLOG(LOG_DEBUG, "invalid message is passed.\n");
2126 return key_senderror(so, m, EINVAL); 2127 return key_senderror(so, m, EINVAL);
2127 } 2128 }
@@ -2206,29 +2207,36 @@ key_api_spdadd(struct socket *so, struct @@ -2206,29 +2207,36 @@ key_api_spdadd(struct socket *so, struct
2206 if (newsp->id == 0) { 2207 if (newsp->id == 0) {
2207 kmem_free(newsp, sizeof(*newsp)); 2208 kmem_free(newsp, sizeof(*newsp));
2208 return key_senderror(so, m, ENOBUFS); 2209 return key_senderror(so, m, ENOBUFS);
2209 } 2210 }
2210 2211
2211 newsp->spidx = spidx; 2212 newsp->spidx = spidx;
2212 newsp->created = time_uptime; 2213 newsp->created = time_uptime;
2213 newsp->lastused = newsp->created; 2214 newsp->lastused = newsp->created;
2214 newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0; 2215 newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0;
2215 newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0; 2216 newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0;
2216 2217
2217 key_init_sp(newsp); 2218 key_init_sp(newsp);
2218 2219
 2220 sadb_x_policy_id = newsp->id;
 2221
2219 mutex_enter(&key_spd.lock); 2222 mutex_enter(&key_spd.lock);
2220 SPLIST_WRITER_INSERT_TAIL(newsp->spidx.dir, newsp); 2223 SPLIST_WRITER_INSERT_TAIL(newsp->spidx.dir, newsp);
2221 mutex_exit(&key_spd.lock); 2224 mutex_exit(&key_spd.lock);
 2225 /*
 2226 * We don't have a reference to newsp, so we must not touch newsp from
 2227 * now on. If you want to do, you must take a reference beforehand.
 2228 */
 2229 newsp = NULL;
2222 2230
2223#ifdef notyet 2231#ifdef notyet
2224 /* delete the entry in key_misc.spacqlist */ 2232 /* delete the entry in key_misc.spacqlist */
2225 if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) { 2233 if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
2226 struct secspacq *spacq = key_getspacq(&spidx); 2234 struct secspacq *spacq = key_getspacq(&spidx);
2227 if (spacq != NULL) { 2235 if (spacq != NULL) {
2228 /* reset counter in order to deletion by timehandler. */ 2236 /* reset counter in order to deletion by timehandler. */
2229 spacq->created = time_uptime; 2237 spacq->created = time_uptime;
2230 spacq->count = 0; 2238 spacq->count = 0;
2231 } 2239 }
2232 } 2240 }
2233#endif 2241#endif
2234 2242
@@ -2264,27 +2272,27 @@ key_api_spdadd(struct socket *so, struct @@ -2264,27 +2272,27 @@ key_api_spdadd(struct socket *so, struct
2264 key_fill_replymsg(n, 0); 2272 key_fill_replymsg(n, 0);
2265 off = 0; 2273 off = 0;
2266 mpolicy = m_pulldown(n, PFKEY_ALIGN8(sizeof(struct sadb_msg)), 2274 mpolicy = m_pulldown(n, PFKEY_ALIGN8(sizeof(struct sadb_msg)),
2267 sizeof(*xpl), &off); 2275 sizeof(*xpl), &off);
2268 if (mpolicy == NULL) { 2276 if (mpolicy == NULL) {
2269 /* n is already freed */ 2277 /* n is already freed */
2270 return key_senderror(so, m, ENOBUFS); 2278 return key_senderror(so, m, ENOBUFS);
2271 } 2279 }
2272 xpl = (struct sadb_x_policy *)(mtod(mpolicy, char *) + off); 2280 xpl = (struct sadb_x_policy *)(mtod(mpolicy, char *) + off);
2273 if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) { 2281 if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) {
2274 m_freem(n); 2282 m_freem(n);
2275 return key_senderror(so, m, EINVAL); 2283 return key_senderror(so, m, EINVAL);
2276 } 2284 }
2277 xpl->sadb_x_policy_id = newsp->id; 2285 xpl->sadb_x_policy_id = sadb_x_policy_id;
2278 2286
2279 m_freem(m); 2287 m_freem(m);
2280 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL); 2288 return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
2281 } 2289 }
2282} 2290}
2283 2291
2284/* 2292/*
2285 * get new policy id. 2293 * get new policy id.
2286 * OUT: 2294 * OUT:
2287 * 0: failure. 2295 * 0: failure.
2288 * others: success. 2296 * others: success.
2289 */ 2297 */
2290static u_int32_t 2298static u_int32_t