diff options
author | Matt Dunwoodie <ncon@noconroy.net> | 2021-04-21 01:02:20 +1000 |
---|---|---|
committer | Matt Dunwoodie <ncon@noconroy.net> | 2021-04-21 01:02:55 +1000 |
commit | c493910bda9547436080993fb559b81c29242b99 (patch) | |
tree | 9371765b7807bc2d0bdf2dfb35223275422609a3 | |
parent | wg_noise: avoid handshake/keypair type confusion (diff) | |
download | wireguard-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.c | 3 | ||||
-rw-r--r-- | src/wg_noise.c | 25 | ||||
-rw-r--r-- | src/wg_noise.h | 2 |
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]); |