summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorblambert <blambert@openbsd.org>2011-05-11 07:37:04 +0000
committerblambert <blambert@openbsd.org>2011-05-11 07:37:04 +0000
commitf00cd271ecb8d50b616630d9e8f22ce41219a0c9 (patch)
tree8cf5772cae11174312ed799862bcc594457e404a
parentTweak previous from jmc@ (diff)
downloadwireguard-openbsd-f00cd271ecb8d50b616630d9e8f22ce41219a0c9.tar.xz
wireguard-openbsd-f00cd271ecb8d50b616630d9e8f22ce41219a0c9.zip
Pre-allocate memory to avoid sleeping after performing a lookup, which
may lead to a race. ok markus@ mikeb@
-rw-r--r--sys/netinet/ip_ipsp.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c
index c8a90947756..e93c5b0c571 100644
--- a/sys/netinet/ip_ipsp.c
+++ b/sys/netinet/ip_ipsp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipsp.c,v 1.182 2011/03/31 10:36:42 jasper Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.183 2011/05/11 07:37:04 blambert Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
@@ -197,7 +197,7 @@ reserve_spi(u_int rdomain, u_int32_t sspi, u_int32_t tspi,
union sockaddr_union *src, union sockaddr_union *dst,
u_int8_t sproto, int *errval)
{
- struct tdb *tdbp;
+ struct tdb *tdbp, *exists;
u_int32_t spi;
int nums, s;
@@ -236,6 +236,9 @@ reserve_spi(u_int rdomain, u_int32_t sspi, u_int32_t tspi,
else
nums = 100; /* Arbitrarily chosen */
+ /* allocate ahead of time to avoid potential sleeping race in loop */
+ tdbp = tdb_alloc(rdomain);
+
while (nums--) {
if (sspi == tspi) /* Specific SPI asked. */
spi = tspi;
@@ -250,13 +253,12 @@ reserve_spi(u_int rdomain, u_int32_t sspi, u_int32_t tspi,
/* Check whether we're using this SPI already. */
s = spltdb();
- tdbp = gettdb(rdomain, spi, dst, sproto);
+ exists = gettdb(rdomain, spi, dst, sproto);
splx(s);
- if (tdbp != (struct tdb *) NULL)
+ if (exists)
continue;
- tdbp = tdb_alloc(rdomain);
tdbp->tdb_spi = spi;
bcopy(&dst->sa, &tdbp->tdb_dst.sa, SA_LEN(&dst->sa));
@@ -278,6 +280,7 @@ reserve_spi(u_int rdomain, u_int32_t sspi, u_int32_t tspi,
}
(*errval) = EEXIST;
+ tdb_free(tdbp);
return 0;
}