aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon2020-12-15 09:48:22 -0600
committerGiuliano Procida2020-12-30 04:20:47 -0600
commit926e1040f4037b12ffabac4e9a895b0832d3ac42 (patch)
treee06a1920d65d0ca1368a7a02b8e97da171090076
parent342a4badfd6a728f35328b7755da01cba49f051d (diff)
downloadkernel-926e1040f4037b12ffabac4e9a895b0832d3ac42.tar.gz
kernel-926e1040f4037b12ffabac4e9a895b0832d3ac42.tar.xz
kernel-926e1040f4037b12ffabac4e9a895b0832d3ac42.zip
ANDROID: usb: f_accessory: Fix teardown ordering in acc_release()
acc_release() attempts to synchronise with acc_open() using an atomic 'open_excl' member in 'struct acc_dev'. Unfortunately, acc_release() prematurely resets this atomic variable to zero, meaning there is a potential race on 'dev->disconnected': acc_open() acc_release() atomic_xchg(open_excl), 0) atomic_xchg(open_excl, 1) dev->disconnected = 0; dev->disconnected = 1; Fix the race by ensuring that the 'disconnected' field is written before clearing 'open_excl' in acc_release(). Bug: 173789633 Signed-off-by: Will Deacon <willdeacon@google.com> Change-Id: Ib9a21f2305f6d70de3e760da62dbfdd66889200a Signed-off-by: Giuliano Procida <gprocida@google.com>
-rw-r--r--drivers/usb/gadget/function/f_accessory.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c
index 089e27790d29..ab3e47c1083e 100644
--- a/drivers/usb/gadget/function/f_accessory.c
+++ b/drivers/usb/gadget/function/f_accessory.c
@@ -899,13 +899,13 @@ static int acc_release(struct inode *ip, struct file *fp)
899 if (!dev) 899 if (!dev)
900 return -ENOENT; 900 return -ENOENT;
901 901
902 WARN_ON(!atomic_xchg(&dev->open_excl, 0));
903 /* indicate that we are disconnected 902 /* indicate that we are disconnected
904 * still could be online so don't touch online flag 903 * still could be online so don't touch online flag
905 */ 904 */
906 dev->disconnected = 1; 905 dev->disconnected = 1;
907 906
908 fp->private_data = NULL; 907 fp->private_data = NULL;
908 WARN_ON(!atomic_xchg(&dev->open_excl, 0));
909 put_acc_dev(dev); 909 put_acc_dev(dev);
910 return 0; 910 return 0;
911} 911}