linux/drivers
Jason A. Donenfeld 6fedfc7cc3 UPSTREAM: wireguard: noise: take lock when removing handshake entry from table
Eric reported that syzkaller found a race of this variety:

CPU 1                                       CPU 2
-------------------------------------------|---------------------------------------
wg_index_hashtable_replace(old, ...)       |
  if (hlist_unhashed(&old->index_hash))    |
                                           | wg_index_hashtable_remove(old)
                                           |   hlist_del_init_rcu(&old->index_hash)
				           |     old->index_hash.pprev = NULL
  hlist_replace_rcu(&old->index_hash, ...) |
    *old->index_hash.pprev                 |

Syzbot wasn't actually able to reproduce this more than once or create a
reproducer, because the race window between checking "hlist_unhashed" and
calling "hlist_replace_rcu" is just so small. Adding an mdelay(5) or
similar there helps make this demonstrable using this simple script:

    #!/bin/bash
    set -ex
    trap 'kill $pid1; kill $pid2; ip link del wg0; ip link del wg1' EXIT
    ip link add wg0 type wireguard
    ip link add wg1 type wireguard
    wg set wg0 private-key <(wg genkey) listen-port 9999
    wg set wg1 private-key <(wg genkey) peer $(wg show wg0 public-key) endpoint 127.0.0.1:9999 persistent-keepalive 1
    wg set wg0 peer $(wg show wg1 public-key)
    ip link set wg0 up
    yes link set wg1 up | ip -force -batch - &
    pid1=$!
    yes link set wg1 down | ip -force -batch - &
    pid2=$!
    wait

The fundumental underlying problem is that we permit calls to wg_index_
hashtable_remove(handshake.entry) without requiring the caller to take
the handshake mutex that is intended to protect members of handshake
during mutations. This is consistently the case with calls to wg_index_
hashtable_insert(handshake.entry) and wg_index_hashtable_replace(
handshake.entry), but it's missing from a pertinent callsite of wg_
index_hashtable_remove(handshake.entry). So, this patch makes sure that
mutex is taken.

The original code was a little bit funky though, in the form of:

    remove(handshake.entry)
    lock(), memzero(handshake.some_members), unlock()
    remove(handshake.entry)

The original intention of that double removal pattern outside the lock
appears to be some attempt to prevent insertions that might happen while
locks are dropped during expensive crypto operations, but actually, all
callers of wg_index_hashtable_insert(handshake.entry) take the write
lock and then explicitly check handshake.state, as they should, which
the aforementioned memzero clears, which means an insertion should
already be impossible. And regardless, the original intention was
necessarily racy, since it wasn't guaranteed that something else would
run after the unlock() instead of after the remove(). So, from a
soundness perspective, it seems positive to remove what looks like a
hack at best.

The crash from both syzbot and from the script above is as follows:

  general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN
  KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
  CPU: 0 PID: 7395 Comm: kworker/0:3 Not tainted 5.9.0-rc4-syzkaller #0
  Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
  Workqueue: wg-kex-wg1 wg_packet_handshake_receive_worker
  RIP: 0010:hlist_replace_rcu include/linux/rculist.h:505 [inline]
  RIP: 0010:wg_index_hashtable_replace+0x176/0x330 drivers/net/wireguard/peerlookup.c:174
  Code: 00 fc ff df 48 89 f9 48 c1 e9 03 80 3c 01 00 0f 85 44 01 00 00 48 b9 00 00 00 00 00 fc ff df 48 8b 45 10 48 89 c6 48 c1 ee 03 <80> 3c 0e 00 0f 85 06 01 00 00 48 85 d2 4c 89 28 74 47 e8 a3 4f b5
  RSP: 0018:ffffc90006a97bf8 EFLAGS: 00010246
  RAX: 0000000000000000 RBX: ffff888050ffc4f8 RCX: dffffc0000000000
  RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88808e04e010
  RBP: ffff88808e04e000 R08: 0000000000000001 R09: ffff8880543d0000
  R10: ffffed100a87a000 R11: 000000000000016e R12: ffff8880543d0000
  R13: ffff88808e04e008 R14: ffff888050ffc508 R15: ffff888050ffc500
  FS:  0000000000000000(0000) GS:ffff8880ae600000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00000000f5505db0 CR3: 0000000097cf7000 CR4: 00000000001526f0
  DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
  DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
  Call Trace:
  wg_noise_handshake_begin_session+0x752/0xc9a drivers/net/wireguard/noise.c:820
  wg_receive_handshake_packet drivers/net/wireguard/receive.c:183 [inline]
  wg_packet_handshake_receive_worker+0x33b/0x730 drivers/net/wireguard/receive.c:220
  process_one_work+0x94c/0x1670 kernel/workqueue.c:2269
  worker_thread+0x64c/0x1120 kernel/workqueue.c:2415
  kthread+0x3b5/0x4a0 kernel/kthread.c:292
  ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:294

Reported-by: syzbot <syzkaller@googlegroups.com>
Reported-by: Eric Dumazet <edumazet@google.com>
Link: https://lore.kernel.org/wireguard/20200908145911.4090480-1-edumazet@google.com/
Fixes: e7096c131e ("net: WireGuard secure network tunnel")
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 9179ba3136)
Bug: 152722841
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I5d1ca2bb77b61c654b2f56660a6b1c3f5fb2446f
2020-10-25 13:40:27 +01:00
..
accessibility
acpi This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
amba
android UPSTREAM: binder: fix UAF when releasing todo list 2020-10-17 13:15:39 +02:00
ata ata: sata_mv, avoid trigerrable BUG_ON 2020-10-01 13:14:54 +02:00
atm atm: eni: fix the missed pci_disable_device() for eni_init_one() 2020-10-01 13:14:51 +02:00
auxdisplay
base This is the 4.19.151 stable release 2020-10-14 12:11:08 +02:00
bcma bcma: fix incorrect update of BCMA_CORE_PCI_MDIO_DATA 2020-01-27 14:51:09 +01:00
block This is the 4.19.146 stable release 2020-09-17 13:59:19 +02:00
bluetooth Bluetooth: btrtl: Use kvmalloc for FW allocations 2020-10-01 13:14:31 +02:00
bus bus: hisi_lpc: Fixup IO ports addresses to avoid use-after-free in host removal 2020-10-01 13:14:35 +02:00
cdrom
char This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
clk This is the 4.19.150 stable release 2020-10-07 08:45:35 +02:00
clocksource This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
connector
cpufreq This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
cpuidle This is the 4.19.144 stable release 2020-09-09 19:48:58 +02:00
crypto This is the 4.19.152 stable release 2020-10-17 10:26:40 +02:00
dax
dca
devfreq This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
dio
dma dmaengine: tegra-apb: Prevent race conditions on channel's freeing 2020-10-01 13:14:35 +02:00
dma-buf This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
edac This is the 4.19.143 stable release 2020-09-03 13:19:20 +02:00
eisa
energy_model
extcon This is the 4.19.130 stable release 2020-06-27 09:50:13 +02:00
firewire
firmware This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
fmc
fpga fpga: dfl: fix bug in port reset handshake 2020-07-29 10:16:48 +02:00
fsi fsi: sbefifo: Don't fail operations when in SBE IPL state 2020-01-27 14:51:00 +01:00
gnss This is the 4.19.129 stable release 2020-06-22 10:50:54 +02:00
gpio This is the 4.19.150 stable release 2020-10-07 08:45:35 +02:00
gpu This is the 4.19.151 stable release 2020-10-14 12:11:08 +02:00
hid This is the 4.19.146 stable release 2020-09-17 13:59:19 +02:00
hsi
hv Drivers: hv: vmbus: Add timeout to vmbus_wait_for_unload 2020-09-23 12:10:59 +02:00
hwmon This is the 4.19.144 stable release 2020-09-09 19:48:58 +02:00
hwspinlock
hwtracing This is the 4.19.140 stable release 2020-08-19 08:43:22 +02:00
i2c This is the 4.19.151 stable release 2020-10-14 12:11:08 +02:00
ide ide: serverworks: potential overflow in svwks_set_pio_mode() 2020-02-24 08:34:49 +01:00
idle
iio This is the 4.19.146 stable release 2020-09-17 13:59:19 +02:00
infiniband This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
input This is the 4.19.150 stable release 2020-10-07 08:45:35 +02:00
iommu This is the 4.19.150 stable release 2020-10-07 08:45:35 +02:00
ipack ipack: tpci200: fix error return code in tpci200_register() 2020-05-27 17:37:43 +02:00
irqchip This is the 4.19.143 stable release 2020-09-03 13:19:20 +02:00
isdn PCI: add USR vendor id and use it in r8169 and w6692 driver 2020-06-22 09:05:23 +02:00
leds leds: mlxreg: Fix possible buffer overflow 2020-10-01 13:14:25 +02:00
lightnvm lightnvm: pblk: fix lock order in pblk_rb_tear_down_check 2020-01-27 14:50:45 +01:00
macintosh drivers/macintosh: Fix memleak in windfarm_pm112 driver 2020-06-22 09:05:29 +02:00
mailbox ANDROID: GKI: drivers: mailbox: fix race resulting in multiple message submission 2020-04-30 00:05:52 -07:00
mcb
md This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
media This is the 4.19.152 stable release 2020-10-17 10:26:40 +02:00
memory
memstick
message scsi: mptscsih: Fix read sense data size 2020-07-16 08:17:23 +02:00
mfd mfd: mfd-core: Protect against NULL call-back function pointer 2020-10-01 13:14:26 +02:00
misc This is the 4.19.140 stable release 2020-08-19 08:43:22 +02:00
mmc This is the 4.19.151 stable release 2020-10-14 12:11:08 +02:00
mtd mtd: rawnand: sunxi: Fix the probe error path 2020-10-14 10:31:22 +02:00
mux
net UPSTREAM: wireguard: noise: take lock when removing handshake entry from table 2020-10-25 13:40:27 +01:00
nfc NFC: st95hf: Fix memleak in st95hf_in_send_cmd 2020-09-17 13:45:24 +02:00
ntb NTB: perf: Fix race condition when run with ntb_test 2020-06-25 15:33:03 +02:00
nubus
nvdimm This is the 4.19.127 stable release 2020-06-07 14:25:43 +02:00
nvme nvme-core: put ctrl ref when module ref get fail 2020-10-14 10:31:22 +02:00
nvmem This is the 4.19.128 stable release 2020-06-11 09:16:29 +02:00
of This is the 4.19.134 stable release 2020-07-22 13:03:12 +02:00
opp This is the 4.19.99 stable release 2020-01-27 15:55:44 +01:00
oprofile
parisc parisc: mask out enable and reserved bits from sba imask 2020-08-19 08:15:07 +02:00
parport
pci This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
pcmcia
perf drivers/perf: hisi: Fix wrong value for all counters enable 2020-06-25 15:33:04 +02:00
phy phy: samsung: s5pv210-usb2: Add delay after reset 2020-10-01 13:14:44 +02:00
pinctrl pinctrl: mvebu: Fix i2c sda definition for 98DX3236 2020-10-07 08:00:07 +02:00
platform This is the 4.19.151 stable release 2020-10-14 12:11:08 +02:00
pnp
power This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
powercap
pps
ps3
ptp
pwm This is the 4.19.141 stable release 2020-08-21 13:01:46 +02:00
rapidio rapidio: avoid data race between file operation callbacks and mport_cdev_add(). 2020-10-01 13:14:48 +02:00
ras
regulator This is the 4.19.147 stable release 2020-09-24 12:48:04 +02:00
remoteproc remoteproc: qcom: q6v5: Update running state before requesting stop 2020-08-21 11:05:34 +02:00
reset reset: uniphier: Add SCSSI reset control for each channel 2020-02-24 08:34:44 +01:00
rpmsg rpmsg: glink: Remove chunk size word align warning 2020-04-13 10:45:16 +02:00
rtc This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
s390 s390/zcrypt: Fix ZCRYPT_PERDEV_REQCNT ioctl 2020-10-01 13:14:54 +02:00
sbus
scsi This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
sfi
sh
siox
slimbus slimbus: core: Fix mismatch in of_node_get/put 2020-07-22 09:32:07 +02:00
sn
soc This is the 4.19.140 stable release 2020-08-19 08:43:22 +02:00
soundwire
spi This is the 4.19.150 stable release 2020-10-07 08:45:35 +02:00
spmi Revert "ANDROID: GKI: spmi: pmic-arb: don't enable SPMI_MSM_PMIC_ARB by default" 2020-05-01 19:41:44 +00:00
ssb
staging This is the 4.19.152 stable release 2020-10-17 10:26:40 +02:00
target scsi: target: iscsi: Fix hang in iscsit_access_np() when getting tpg->np_login_sem 2020-09-17 13:45:29 +02:00
tc
tee This is the 4.19.102 stable release 2020-02-05 19:20:26 +00:00
thermal This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
thunderbolt thunderbolt: Drop duplicated get_switch_at_route() 2020-05-27 17:37:40 +02:00
tty This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
uio uio_pdrv_genirq: fix use without device tree and no interrupt 2020-07-22 09:32:11 +02:00
usb This is the 4.19.152 stable release 2020-10-17 10:26:40 +02:00
uwb
vfio This is the 4.19.149 stable release 2020-10-01 16:49:05 +02:00
vhost This is the 4.19.150 stable release 2020-10-07 08:45:35 +02:00
video fbcon: Fix global-out-of-bounds read in fbcon_get_font() 2020-10-14 10:31:21 +02:00
virt virt: vbox: Fix guest capabilities mask check 2020-07-22 09:32:10 +02:00
virtio This is the 4.19.142 stable release 2020-08-26 11:07:03 +02:00
visorbus visorbus: fix uninitialized variable access 2020-02-24 08:34:47 +01:00
vlynq
vme vme: bridges: reduce stack usage 2020-02-24 08:34:47 +01:00
w1 w1: omap-hdq: cleanup to add missing newline for some dev_dbg 2020-06-22 09:05:30 +02:00
watchdog watchdog: initialize device before misc_register 2020-08-21 11:05:37 +02:00
xen xen/xenbus: Fix granting of vmalloc'd memory 2020-09-09 19:04:24 +02:00
zorro
Kconfig UPSTREAM: gpu/trace: add a gpu total memory usage tracepoint 2020-04-21 15:34:05 +00:00
Makefile