Merge branch 'wireguard-fixes-for-6-9-rc1'
Jason A. Donenfeld says: ==================== wireguard fixes for 6.9-rc1 This series has four WireGuard fixes: 1) Annotate a data race that KCSAN found by using READ_ONCE/WRITE_ONCE, which has been causing syzkaller noise. 2) Use the generic netdev tstats allocation and stats getters instead of doing this within the driver. 3) Explicitly check a flag variable instead of an empty list in the netlink code, to prevent a UaF situation when paging through GET results during a remove-all SET operation. 4) Set a flag in the RISC-V CI config so the selftests continue to boot. ==================== Link: https://lore.kernel.org/r/20240314224911.6653-1-Jason@zx2c4.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
710fe438e3
@ -237,7 +237,6 @@ static const struct net_device_ops netdev_ops = {
|
||||
.ndo_open = wg_open,
|
||||
.ndo_stop = wg_stop,
|
||||
.ndo_start_xmit = wg_xmit,
|
||||
.ndo_get_stats64 = dev_get_tstats64
|
||||
};
|
||||
|
||||
static void wg_destruct(struct net_device *dev)
|
||||
@ -262,7 +261,6 @@ static void wg_destruct(struct net_device *dev)
|
||||
rcu_barrier(); /* Wait for all the peers to be actually freed. */
|
||||
wg_ratelimiter_uninit();
|
||||
memzero_explicit(&wg->static_identity, sizeof(wg->static_identity));
|
||||
free_percpu(dev->tstats);
|
||||
kvfree(wg->index_hashtable);
|
||||
kvfree(wg->peer_hashtable);
|
||||
mutex_unlock(&wg->device_update_lock);
|
||||
@ -297,6 +295,7 @@ static void wg_setup(struct net_device *dev)
|
||||
dev->hw_enc_features |= WG_NETDEV_FEATURES;
|
||||
dev->mtu = ETH_DATA_LEN - overhead;
|
||||
dev->max_mtu = round_down(INT_MAX, MESSAGE_PADDING_MULTIPLE) - overhead;
|
||||
dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
|
||||
|
||||
SET_NETDEV_DEVTYPE(dev, &device_type);
|
||||
|
||||
@ -331,14 +330,10 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
|
||||
if (!wg->index_hashtable)
|
||||
goto err_free_peer_hashtable;
|
||||
|
||||
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
|
||||
if (!dev->tstats)
|
||||
goto err_free_index_hashtable;
|
||||
|
||||
wg->handshake_receive_wq = alloc_workqueue("wg-kex-%s",
|
||||
WQ_CPU_INTENSIVE | WQ_FREEZABLE, 0, dev->name);
|
||||
if (!wg->handshake_receive_wq)
|
||||
goto err_free_tstats;
|
||||
goto err_free_index_hashtable;
|
||||
|
||||
wg->handshake_send_wq = alloc_workqueue("wg-kex-%s",
|
||||
WQ_UNBOUND | WQ_FREEZABLE, 0, dev->name);
|
||||
@ -397,8 +392,6 @@ err_destroy_handshake_send:
|
||||
destroy_workqueue(wg->handshake_send_wq);
|
||||
err_destroy_handshake_receive:
|
||||
destroy_workqueue(wg->handshake_receive_wq);
|
||||
err_free_tstats:
|
||||
free_percpu(dev->tstats);
|
||||
err_free_index_hashtable:
|
||||
kvfree(wg->index_hashtable);
|
||||
err_free_peer_hashtable:
|
||||
|
@ -164,8 +164,8 @@ get_peer(struct wg_peer *peer, struct sk_buff *skb, struct dump_ctx *ctx)
|
||||
if (!allowedips_node)
|
||||
goto no_allowedips;
|
||||
if (!ctx->allowedips_seq)
|
||||
ctx->allowedips_seq = peer->device->peer_allowedips.seq;
|
||||
else if (ctx->allowedips_seq != peer->device->peer_allowedips.seq)
|
||||
ctx->allowedips_seq = ctx->wg->peer_allowedips.seq;
|
||||
else if (ctx->allowedips_seq != ctx->wg->peer_allowedips.seq)
|
||||
goto no_allowedips;
|
||||
|
||||
allowedips_nest = nla_nest_start(skb, WGPEER_A_ALLOWEDIPS);
|
||||
@ -255,17 +255,17 @@ static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
if (!peers_nest)
|
||||
goto out;
|
||||
ret = 0;
|
||||
/* If the last cursor was removed via list_del_init in peer_remove, then
|
||||
lockdep_assert_held(&wg->device_update_lock);
|
||||
/* If the last cursor was removed in peer_remove or peer_remove_all, then
|
||||
* we just treat this the same as there being no more peers left. The
|
||||
* reason is that seq_nr should indicate to userspace that this isn't a
|
||||
* coherent dump anyway, so they'll try again.
|
||||
*/
|
||||
if (list_empty(&wg->peer_list) ||
|
||||
(ctx->next_peer && list_empty(&ctx->next_peer->peer_list))) {
|
||||
(ctx->next_peer && ctx->next_peer->is_dead)) {
|
||||
nla_nest_cancel(skb, peers_nest);
|
||||
goto out;
|
||||
}
|
||||
lockdep_assert_held(&wg->device_update_lock);
|
||||
peer = list_prepare_entry(ctx->next_peer, &wg->peer_list, peer_list);
|
||||
list_for_each_entry_continue(peer, &wg->peer_list, peer_list) {
|
||||
if (get_peer(peer, skb, ctx)) {
|
||||
|
@ -251,7 +251,7 @@ static bool decrypt_packet(struct sk_buff *skb, struct noise_keypair *keypair)
|
||||
|
||||
if (unlikely(!READ_ONCE(keypair->receiving.is_valid) ||
|
||||
wg_birthdate_has_expired(keypair->receiving.birthdate, REJECT_AFTER_TIME) ||
|
||||
keypair->receiving_counter.counter >= REJECT_AFTER_MESSAGES)) {
|
||||
READ_ONCE(keypair->receiving_counter.counter) >= REJECT_AFTER_MESSAGES)) {
|
||||
WRITE_ONCE(keypair->receiving.is_valid, false);
|
||||
return false;
|
||||
}
|
||||
@ -318,7 +318,7 @@ static bool counter_validate(struct noise_replay_counter *counter, u64 their_cou
|
||||
for (i = 1; i <= top; ++i)
|
||||
counter->backtrack[(i + index_current) &
|
||||
((COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1)] = 0;
|
||||
counter->counter = their_counter;
|
||||
WRITE_ONCE(counter->counter, their_counter);
|
||||
}
|
||||
|
||||
index &= (COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1;
|
||||
@ -463,7 +463,7 @@ int wg_packet_rx_poll(struct napi_struct *napi, int budget)
|
||||
net_dbg_ratelimited("%s: Packet has invalid nonce %llu (max %llu)\n",
|
||||
peer->device->dev->name,
|
||||
PACKET_CB(skb)->nonce,
|
||||
keypair->receiving_counter.counter);
|
||||
READ_ONCE(keypair->receiving_counter.counter));
|
||||
goto next;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ CONFIG_ARCH_RV32I=y
|
||||
CONFIG_MMU=y
|
||||
CONFIG_FPU=y
|
||||
CONFIG_SOC_VIRT=y
|
||||
CONFIG_RISCV_ISA_FALLBACK=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
|
@ -2,6 +2,7 @@ CONFIG_ARCH_RV64I=y
|
||||
CONFIG_MMU=y
|
||||
CONFIG_FPU=y
|
||||
CONFIG_SOC_VIRT=y
|
||||
CONFIG_RISCV_ISA_FALLBACK=y
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
|
Loading…
x
Reference in New Issue
Block a user