linux/drivers
Jason A. Donenfeld 47c578038a UPSTREAM: wireguard: noise: reject peers with low order public keys
Our static-static calculation returns a failure if the public key is of
low order. We check for this when peers are added, and don't allow them
to be added if they're low order, except in the case where we haven't
yet been given a private key. In that case, we would defer the removal
of the peer until we're given a private key, since at that point we're
doing new static-static calculations which incur failures we can act on.
This meant, however, that we wound up removing peers rather late in the
configuration flow.

Syzkaller points out that peer_remove calls flush_workqueue, which in
turn might then wait for sending a handshake initiation to complete.
Since handshake initiation needs the static identity lock, holding the
static identity lock while calling peer_remove can result in a rare
deadlock. We have precisely this case in this situation of late-stage
peer removal based on an invalid public key. We can't drop the lock when
removing, because then incoming handshakes might interact with a bogus
static-static calculation.

While the band-aid patch for this would involve breaking up the peer
removal into two steps like wg_peer_remove_all does, in order to solve
the locking issue, there's actually a much more elegant way of fixing
this:

If the static-static calculation succeeds with one private key, it
*must* succeed with all others, because all 32-byte strings map to valid
private keys, thanks to clamping. That means we can get rid of this
silly dance and locking headaches of removing peers late in the
configuration flow, and instead just reject them early on, regardless of
whether the device has yet been assigned a private key. For the case
where the device doesn't yet have a private key, we safely use zeros
just for the purposes of checking for low order points by way of
checking the output of the calculation.

The following PoC will trigger the deadlock:

ip link add wg0 type wireguard
ip addr add 10.0.0.1/24 dev wg0
ip link set wg0 up
ping -f 10.0.0.2 &
while true; do
        wg set wg0 private-key /dev/null peer AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= allowed-ips 10.0.0.0/24 endpoint 10.0.0.3:1234
        wg set wg0 private-key <(echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=)
done

[    0.949105] ======================================================
[    0.949550] WARNING: possible circular locking dependency detected
[    0.950143] 5.5.0-debug+ #18 Not tainted
[    0.950431] ------------------------------------------------------
[    0.950959] wg/89 is trying to acquire lock:
[    0.951252] ffff8880333e2128 ((wq_completion)wg-kex-wg0){+.+.}, at: flush_workqueue+0xe3/0x12f0
[    0.951865]
[    0.951865] but task is already holding lock:
[    0.952280] ffff888032819bc0 (&wg->static_identity.lock){++++}, at: wg_set_device+0x95d/0xcc0
[    0.953011]
[    0.953011] which lock already depends on the new lock.
[    0.953011]
[    0.953651]
[    0.953651] the existing dependency chain (in reverse order) is:
[    0.954292]
[    0.954292] -> #2 (&wg->static_identity.lock){++++}:
[    0.954804]        lock_acquire+0x127/0x350
[    0.955133]        down_read+0x83/0x410
[    0.955428]        wg_noise_handshake_create_initiation+0x97/0x700
[    0.955885]        wg_packet_send_handshake_initiation+0x13a/0x280
[    0.956401]        wg_packet_handshake_send_worker+0x10/0x20
[    0.956841]        process_one_work+0x806/0x1500
[    0.957167]        worker_thread+0x8c/0xcb0
[    0.957549]        kthread+0x2ee/0x3b0
[    0.957792]        ret_from_fork+0x24/0x30
[    0.958234]
[    0.958234] -> #1 ((work_completion)(&peer->transmit_handshake_work)){+.+.}:
[    0.958808]        lock_acquire+0x127/0x350
[    0.959075]        process_one_work+0x7ab/0x1500
[    0.959369]        worker_thread+0x8c/0xcb0
[    0.959639]        kthread+0x2ee/0x3b0
[    0.959896]        ret_from_fork+0x24/0x30
[    0.960346]
[    0.960346] -> #0 ((wq_completion)wg-kex-wg0){+.+.}:
[    0.960945]        check_prev_add+0x167/0x1e20
[    0.961351]        __lock_acquire+0x2012/0x3170
[    0.961725]        lock_acquire+0x127/0x350
[    0.961990]        flush_workqueue+0x106/0x12f0
[    0.962280]        peer_remove_after_dead+0x160/0x220
[    0.962600]        wg_set_device+0xa24/0xcc0
[    0.962994]        genl_rcv_msg+0x52f/0xe90
[    0.963298]        netlink_rcv_skb+0x111/0x320
[    0.963618]        genl_rcv+0x1f/0x30
[    0.963853]        netlink_unicast+0x3f6/0x610
[    0.964245]        netlink_sendmsg+0x700/0xb80
[    0.964586]        __sys_sendto+0x1dd/0x2c0
[    0.964854]        __x64_sys_sendto+0xd8/0x1b0
[    0.965141]        do_syscall_64+0x90/0xd9a
[    0.965408]        entry_SYSCALL_64_after_hwframe+0x49/0xbe
[    0.965769]
[    0.965769] other info that might help us debug this:
[    0.965769]
[    0.966337] Chain exists of:
[    0.966337]   (wq_completion)wg-kex-wg0 --> (work_completion)(&peer->transmit_handshake_work) --> &wg->static_identity.lock
[    0.966337]
[    0.967417]  Possible unsafe locking scenario:
[    0.967417]
[    0.967836]        CPU0                    CPU1
[    0.968155]        ----                    ----
[    0.968497]   lock(&wg->static_identity.lock);
[    0.968779]                                lock((work_completion)(&peer->transmit_handshake_work));
[    0.969345]                                lock(&wg->static_identity.lock);
[    0.969809]   lock((wq_completion)wg-kex-wg0);
[    0.970146]
[    0.970146]  *** DEADLOCK ***
[    0.970146]
[    0.970531] 5 locks held by wg/89:
[    0.970908]  #0: ffffffff827433c8 (cb_lock){++++}, at: genl_rcv+0x10/0x30
[    0.971400]  #1: ffffffff82743480 (genl_mutex){+.+.}, at: genl_rcv_msg+0x642/0xe90
[    0.971924]  #2: ffffffff827160c0 (rtnl_mutex){+.+.}, at: wg_set_device+0x9f/0xcc0
[    0.972488]  #3: ffff888032819de0 (&wg->device_update_lock){+.+.}, at: wg_set_device+0xb0/0xcc0
[    0.973095]  #4: ffff888032819bc0 (&wg->static_identity.lock){++++}, at: wg_set_device+0x95d/0xcc0
[    0.973653]
[    0.973653] stack backtrace:
[    0.973932] CPU: 1 PID: 89 Comm: wg Not tainted 5.5.0-debug+ #18
[    0.974476] Call Trace:
[    0.974638]  dump_stack+0x97/0xe0
[    0.974869]  check_noncircular+0x312/0x3e0
[    0.975132]  ? print_circular_bug+0x1f0/0x1f0
[    0.975410]  ? __kernel_text_address+0x9/0x30
[    0.975727]  ? unwind_get_return_address+0x51/0x90
[    0.976024]  check_prev_add+0x167/0x1e20
[    0.976367]  ? graph_lock+0x70/0x160
[    0.976682]  __lock_acquire+0x2012/0x3170
[    0.976998]  ? register_lock_class+0x1140/0x1140
[    0.977323]  lock_acquire+0x127/0x350
[    0.977627]  ? flush_workqueue+0xe3/0x12f0
[    0.977890]  flush_workqueue+0x106/0x12f0
[    0.978147]  ? flush_workqueue+0xe3/0x12f0
[    0.978410]  ? find_held_lock+0x2c/0x110
[    0.978662]  ? lock_downgrade+0x6e0/0x6e0
[    0.978919]  ? queue_rcu_work+0x60/0x60
[    0.979166]  ? netif_napi_del+0x151/0x3b0
[    0.979501]  ? peer_remove_after_dead+0x160/0x220
[    0.979871]  peer_remove_after_dead+0x160/0x220
[    0.980232]  wg_set_device+0xa24/0xcc0
[    0.980516]  ? deref_stack_reg+0x8e/0xc0
[    0.980801]  ? set_peer+0xe10/0xe10
[    0.981040]  ? __ww_mutex_check_waiters+0x150/0x150
[    0.981430]  ? __nla_validate_parse+0x163/0x270
[    0.981719]  ? genl_family_rcv_msg_attrs_parse+0x13f/0x310
[    0.982078]  genl_rcv_msg+0x52f/0xe90
[    0.982348]  ? genl_family_rcv_msg_attrs_parse+0x310/0x310
[    0.982690]  ? register_lock_class+0x1140/0x1140
[    0.983049]  netlink_rcv_skb+0x111/0x320
[    0.983298]  ? genl_family_rcv_msg_attrs_parse+0x310/0x310
[    0.983645]  ? netlink_ack+0x880/0x880
[    0.983888]  genl_rcv+0x1f/0x30
[    0.984168]  netlink_unicast+0x3f6/0x610
[    0.984443]  ? netlink_detachskb+0x60/0x60
[    0.984729]  ? find_held_lock+0x2c/0x110
[    0.984976]  netlink_sendmsg+0x700/0xb80
[    0.985220]  ? netlink_broadcast_filtered+0xa60/0xa60
[    0.985533]  __sys_sendto+0x1dd/0x2c0
[    0.985763]  ? __x64_sys_getpeername+0xb0/0xb0
[    0.986039]  ? sockfd_lookup_light+0x17/0x160
[    0.986397]  ? __sys_recvmsg+0x8c/0xf0
[    0.986711]  ? __sys_recvmsg_sock+0xd0/0xd0
[    0.987018]  __x64_sys_sendto+0xd8/0x1b0
[    0.987283]  ? lockdep_hardirqs_on+0x39b/0x5a0
[    0.987666]  do_syscall_64+0x90/0xd9a
[    0.987903]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[    0.988223] RIP: 0033:0x7fe77c12003e
[    0.988508] Code: c3 8b 07 85 c0 75 24 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 4
[    0.989666] RSP: 002b:00007fffada2ed58 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
[    0.990137] RAX: ffffffffffffffda RBX: 00007fe77c159d48 RCX: 00007fe77c12003e
[    0.990583] RDX: 0000000000000040 RSI: 000055fd1d38e020 RDI: 0000000000000004
[    0.991091] RBP: 000055fd1d38e020 R08: 000055fd1cb63358 R09: 000000000000000c
[    0.991568] R10: 0000000000000000 R11: 0000000000000246 R12: 000000000000002c
[    0.992014] R13: 0000000000000004 R14: 000055fd1d38e020 R15: 0000000000000001

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit ec31c2676a)
Bug: 152722841
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I860bfac72c98c8c9b26f4490b4f346dc67892f87
2020-10-25 13:40:07 +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: reject peers with low order public keys 2020-10-25 13:40:07 +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