aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Dunwoodie <ncon@noconroy.net>2021-04-21 01:02:20 +1000
committerMatt Dunwoodie <ncon@noconroy.net>2021-04-21 01:02:55 +1000
commitc493910bda9547436080993fb559b81c29242b99 (patch)
tree9371765b7807bc2d0bdf2dfb35223275422609a3
parentwg_noise: avoid handshake/keypair type confusion (diff)
downloadwireguard-freebsd-c493910bda9547436080993fb559b81c29242b99.tar.xz
wireguard-freebsd-c493910bda9547436080993fb559b81c29242b99.zip
wg_noise: ensure we check peer count on hashtable insert
Signed-off-by: Matt Dunwoodie <ncon@noconroy.net>
-rw-r--r--src/if_wg.c3
-rw-r--r--src/wg_noise.c25
-rw-r--r--src/wg_noise.h2
3 files changed, 19 insertions, 11 deletions
diff --git a/src/if_wg.c b/src/if_wg.c
index f41878a..5b5e200 100644
--- a/src/if_wg.c
+++ b/src/if_wg.c
@@ -2152,7 +2152,8 @@ wg_peer_add(struct wg_softc *sc, const nvlist_t *nvl)
}
}
if (need_insert) {
- noise_remote_enable(peer->p_remote);
+ if ((err = noise_remote_enable(peer->p_remote)) != 0)
+ goto out;
TAILQ_INSERT_TAIL(&sc->sc_peers, peer, p_entry);
sc->sc_peers_num++;
if (sc->sc_ifp->if_link_state == LINK_STATE_UP)
diff --git a/src/wg_noise.c b/src/wg_noise.c
index 7e3a198..c11315f 100644
--- a/src/wg_noise.c
+++ b/src/wg_noise.c
@@ -81,7 +81,7 @@ struct noise_remote {
struct noise_index r_index;
CK_LIST_ENTRY(noise_remote) r_entry;
- int r_entry_valid;
+ int r_entry_inserted;
uint8_t r_public[NOISE_PUBLIC_KEY_LEN];
struct rwlock r_handshake_lock;
@@ -288,7 +288,7 @@ noise_remote_alloc(struct noise_local *l, void *arg,
return (NULL);
r->r_index.i_is_keypair = 0;
- r->r_entry_valid = 0;
+ r->r_entry_inserted = 0;
memcpy(r->r_public, public, NOISE_PUBLIC_KEY_LEN);
@@ -314,22 +314,29 @@ noise_remote_alloc(struct noise_local *l, void *arg,
return (r);
}
-void
+int
noise_remote_enable(struct noise_remote *r)
{
struct noise_local *l = r->r_local;
uint64_t idx;
+ int ret = 0;
/* Insert to hashtable */
idx = siphash24(&l->l_hash_key, r->r_public, NOISE_PUBLIC_KEY_LEN) & HT_REMOTE_MASK;
rw_wlock(&l->l_remote_lock);
- if (!r->r_entry_valid && l->l_remote_num < MAX_REMOTE_PER_LOCAL) {
- r->r_entry_valid = 1;
- l->l_remote_num++;
- CK_LIST_INSERT_HEAD(&l->l_remote_hash[idx], r, r_entry);
+ if (!r->r_entry_inserted)
+ if (l->l_remote_num < MAX_REMOTE_PER_LOCAL) {
+ r->r_entry_inserted = 1;
+ l->l_remote_num++;
+ CK_LIST_INSERT_HEAD(&l->l_remote_hash[idx], r, r_entry);
+ } else {
+ ret = ENOSPC;
+ }
}
rw_wunlock(&l->l_remote_lock);
+
+ return ret;
}
void
@@ -338,8 +345,8 @@ noise_remote_disable(struct noise_remote *r)
struct noise_local *l = r->r_local;
/* remove from hashtable */
rw_wlock(&l->l_remote_lock);
- if (r->r_entry_valid) {
- r->r_entry_valid = 1;
+ if (r->r_entry_inserted) {
+ r->r_entry_inserted = 0;
CK_LIST_REMOVE(r, r_entry);
l->l_remote_num--;
};
diff --git a/src/wg_noise.h b/src/wg_noise.h
index aa52e8e..8d7b54e 100644
--- a/src/wg_noise.h
+++ b/src/wg_noise.h
@@ -46,7 +46,7 @@ int noise_local_keys(struct noise_local *,
struct noise_remote *
noise_remote_alloc(struct noise_local *, void *,
const uint8_t[NOISE_PUBLIC_KEY_LEN]);
-void noise_remote_enable(struct noise_remote *);
+int noise_remote_enable(struct noise_remote *);
void noise_remote_disable(struct noise_remote *);
struct noise_remote *
noise_remote_lookup(struct noise_local *, const uint8_t[NOISE_PUBLIC_KEY_LEN]);