summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2019-04-25 18:05:36 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-16 09:17:23 +0200
commitc0759c18e95d72cc889ff0afca9264e2df2fb45e (patch)
tree3a04c86b4864ebbecf9cb6a3409e99516a5e39ee /net
parent6b612ec29abd6cf2589dea89cf0720be0ad0f61e (diff)
downloadlinux-stable-c0759c18e95d72cc889ff0afca9264e2df2fb45e.tar.gz
linux-stable-c0759c18e95d72cc889ff0afca9264e2df2fb45e.tar.bz2
linux-stable-c0759c18e95d72cc889ff0afca9264e2df2fb45e.zip
USB: serial: fix unthrottle races
[ Upstream commit 3f5edd58d040bfa4b74fb89bc02f0bc6b9cd06ab ] Fix two long-standing bugs which could potentially lead to memory corruption or leave the port throttled until it is reopened (on weakly ordered systems), respectively, when read-URB completion races with unthrottle(). First, the URB must not be marked as free before processing is complete to prevent it from being submitted by unthrottle() on another CPU. CPU 1 CPU 2 ================ ================ complete() unthrottle() process_urb(); smp_mb__before_atomic(); set_bit(i, free); if (test_and_clear_bit(i, free)) submit_urb(); Second, the URB must be marked as free before checking the throttled flag to prevent unthrottle() on another CPU from failing to observe that the URB needs to be submitted if complete() sees that the throttled flag is set. CPU 1 CPU 2 ================ ================ complete() unthrottle() set_bit(i, free); throttled = 0; smp_mb__after_atomic(); smp_mb(); if (throttled) if (test_and_clear_bit(i, free)) return; submit_urb(); Note that test_and_clear_bit() only implies barriers when the test is successful. To handle the case where the URB is still in use an explicit barrier needs to be added to unthrottle() for the second race condition. Fixes: d83b405383c9 ("USB: serial: add support for multiple read urbs") Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
0 files changed, 0 insertions, 0 deletions