diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-04-28 19:11:28 -0400 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-04-28 19:27:35 -0400 |
commit | 57fcc8e52c91105cf2d3b314941fa8e8d92a85bf (patch) | |
tree | ac855370dc4f7c7bcd8e23fa2a1a493243d8a98a | |
parent | if_wg: use proper bool for is_retry (diff) | |
download | wireguard-freebsd-57fcc8e52c91105cf2d3b314941fa8e8d92a85bf.tar.xz wireguard-freebsd-57fcc8e52c91105cf2d3b314941fa8e8d92a85bf.zip |
if_wg: do not block for memory when sending buffer
This can be called when locks are held in upper parts of the stack,
resulting in witness splats.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | src/if_wg.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/src/if_wg.c b/src/if_wg.c index 1b23ac5..71b8a2c 100644 --- a/src/if_wg.c +++ b/src/if_wg.c @@ -187,7 +187,7 @@ struct wg_packet { } p_state; }; -STAILQ_HEAD(wg_packet_list ,wg_packet); +STAILQ_HEAD(wg_packet_list, wg_packet); struct wg_queue { struct mtx q_mtx; @@ -930,22 +930,29 @@ wg_send_buf(struct wg_softc *sc, struct wg_endpoint *e, uint8_t *buf, size_t len { struct mbuf *m; int ret = 0; + bool retried = false; retry: - m = m_gethdr(M_WAITOK, MT_DATA); + m = m_gethdr(M_NOWAIT, MT_DATA); + if (!m) { + ret = ENOMEM; + goto out; + } m->m_len = 0; m_copyback(m, 0, len, buf); if (ret == 0) { ret = wg_send(sc, e, m); /* Retry if we couldn't bind to e->e_local */ - if (ret == EADDRNOTAVAIL) { + if (ret == EADDRNOTAVAIL && !retried) { bzero(&e->e_local, sizeof(e->e_local)); + retried = true; goto retry; } } else { ret = wg_send(sc, e, m); } +out: if (ret) DPRINTF(sc, "Unable to send packet: %d\n", ret); } @@ -1233,7 +1240,7 @@ wg_send_initiation(struct wg_peer *peer) pkt.t = WG_PKT_INITIATION; cookie_maker_mac(&peer->p_cookie, &pkt.m, &pkt, - sizeof(pkt)-sizeof(pkt.m)); + sizeof(pkt) - sizeof(pkt.m)); wg_peer_send_buf(peer, (uint8_t *)&pkt, sizeof(pkt)); wg_timers_event_handshake_initiated(peer); } @@ -2982,11 +2989,9 @@ free_none: static void wg_module_deinit(void) { - uma_zdestroy(wg_packet_zone); osd_jail_deregister(wg_osd_jail_slot); cookie_deinit(); - MPASS(LIST_EMPTY(&wg_list)); } |