Thu Aug 23 01:55:38 2018 UTC ()
Don't call key_ismyaddr, which may sleep, in a pserialize read section

Use mutex here instead of pserialize because using mutex is simpler than
using psz+ref, which is another solution, and key_checkspidup isn't called in
any performance-sensitive paths.


(ozaki-r)
diff -r1.256 -r1.257 src/sys/netipsec/key.c

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

--- src/sys/netipsec/key.c 2018/07/04 19:20:25 1.256
+++ src/sys/netipsec/key.c 2018/08/23 01:55:38 1.257
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: key.c,v 1.256 2018/07/04 19:20:25 christos Exp $ */ 1/* $NetBSD: key.c,v 1.257 2018/08/23 01:55:38 ozaki-r Exp $ */
2/* $FreeBSD: key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */ 2/* $FreeBSD: 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.256 2018/07/04 19:20:25 christos Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.257 2018/08/23 01:55:38 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>
@@ -3445,49 +3445,49 @@ key_getsah_ref(const struct secasindex * @@ -3445,49 +3445,49 @@ key_getsah_ref(const struct secasindex *
3445 3445
3446/* 3446/*
3447 * check not to be duplicated SPI. 3447 * check not to be duplicated SPI.
3448 * NOTE: this function is too slow due to searching all SAD. 3448 * NOTE: this function is too slow due to searching all SAD.
3449 * OUT: 3449 * OUT:
3450 * NULL : not found 3450 * NULL : not found
3451 * others : found, pointer to a SA. 3451 * others : found, pointer to a SA.
3452 */ 3452 */
3453static bool 3453static bool
3454key_checkspidup(const struct secasindex *saidx, u_int32_t spi) 3454key_checkspidup(const struct secasindex *saidx, u_int32_t spi)
3455{ 3455{
3456 struct secashead *sah; 3456 struct secashead *sah;
3457 struct secasvar *sav; 3457 struct secasvar *sav;
3458 int s; 
3459 3458
3460 /* check address family */ 3459 /* check address family */
3461 if (saidx->src.sa.sa_family != saidx->dst.sa.sa_family) { 3460 if (saidx->src.sa.sa_family != saidx->dst.sa.sa_family) {
3462 IPSECLOG(LOG_DEBUG, 3461 IPSECLOG(LOG_DEBUG,
3463 "address family mismatched src %u, dst %u.\n", 3462 "address family mismatched src %u, dst %u.\n",
3464 saidx->src.sa.sa_family, saidx->dst.sa.sa_family); 3463 saidx->src.sa.sa_family, saidx->dst.sa.sa_family);
3465 return false; 3464 return false;
3466 } 3465 }
3467 3466
3468 /* check all SAD */ 3467 /* check all SAD */
3469 s = pserialize_read_enter(); 3468 /* key_ismyaddr may sleep, so use mutex, not pserialize, here. */
3470 SAHLIST_READER_FOREACH(sah) { 3469 mutex_enter(&key_sad.lock);
 3470 SAHLIST_WRITER_FOREACH(sah) {
3471 if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst)) 3471 if (!key_ismyaddr((struct sockaddr *)&sah->saidx.dst))
3472 continue; 3472 continue;
3473 sav = key_getsavbyspi(sah, spi); 3473 sav = key_getsavbyspi(sah, spi);
3474 if (sav != NULL) { 3474 if (sav != NULL) {
3475 pserialize_read_exit(s); 
3476 KEY_SA_UNREF(&sav); 3475 KEY_SA_UNREF(&sav);
 3476 mutex_exit(&key_sad.lock);
3477 return true; 3477 return true;
3478 } 3478 }
3479 } 3479 }
3480 pserialize_read_exit(s); 3480 mutex_exit(&key_sad.lock);
3481 3481
3482 return false; 3482 return false;
3483} 3483}
3484 3484
3485/* 3485/*
3486 * search SAD litmited alive SA, protocol, SPI. 3486 * search SAD litmited alive SA, protocol, SPI.
3487 * OUT: 3487 * OUT:
3488 * NULL : not found 3488 * NULL : not found
3489 * others : found, pointer to a SA. 3489 * others : found, pointer to a SA.
3490 */ 3490 */
3491static struct secasvar * 3491static struct secasvar *
3492key_getsavbyspi(struct secashead *sah, u_int32_t spi) 3492key_getsavbyspi(struct secashead *sah, u_int32_t spi)
3493{ 3493{