Module Name: src Committed By: riastradh Date: Sun Mar 6 09:03:42 UTC 2022
Modified Files: src/sys/dev/usb: usb.c Log Message: usb(4): Use atomics for usb_async_proc. This is written under proc_lock and read without it in usb_add_event, so using atomics pacifies the sanitizer. No memory ordering needed because the value isn't actually used until the softint runs, using it under proc_lock. Kind of a micro-optimization, but let's avoid contention on proc_lock in the common case of no usb_async_proc set up (why is this a system global, anyway? and why is there a softint if usb_add_event always runs at IPL_NONE?). Reported-by: syzbot+1b2fa68535e5b0f3d...@syzkaller.appspotmail.com To generate a diff of this commit: cvs rdiff -u -r1.198 -r1.199 src/sys/dev/usb/usb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/usb.c diff -u src/sys/dev/usb/usb.c:1.198 src/sys/dev/usb/usb.c:1.199 --- src/sys/dev/usb/usb.c:1.198 Sun Oct 10 20:14:09 2021 +++ src/sys/dev/usb/usb.c Sun Mar 6 09:03:42 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: usb.c,v 1.198 2021/10/10 20:14:09 jmcneill Exp $ */ +/* $NetBSD: usb.c,v 1.199 2022/03/06 09:03:42 riastradh Exp $ */ /* * Copyright (c) 1998, 2002, 2008, 2012 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.198 2021/10/10 20:14:09 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.199 2022/03/06 09:03:42 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -833,7 +833,7 @@ usbopen(dev_t dev, int flag, int mode, s return EBUSY; usb_dev_open = 1; mutex_enter(&proc_lock); - usb_async_proc = NULL; + atomic_store_relaxed(&usb_async_proc, NULL); mutex_exit(&proc_lock); return 0; } @@ -913,7 +913,7 @@ usbclose(dev_t dev, int flag, int mode, if (unit == USB_DEV_MINOR) { mutex_enter(&proc_lock); - usb_async_proc = NULL; + atomic_store_relaxed(&usb_async_proc, NULL); mutex_exit(&proc_lock); usb_dev_open = 0; } @@ -937,10 +937,8 @@ usbioctl(dev_t devt, u_long cmd, void *d case FIOASYNC: mutex_enter(&proc_lock); - if (*(int *)data) - usb_async_proc = l->l_proc; - else - usb_async_proc = NULL; + atomic_store_relaxed(&usb_async_proc, + *(int *)data ? l->l_proc : NULL); mutex_exit(&proc_lock); return 0; @@ -1317,7 +1315,7 @@ usb_add_event(int type, struct usb_event SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); cv_signal(&usb_event_cv); selnotify(&usb_selevent, 0, 0); - if (usb_async_proc != NULL) { + if (atomic_load_relaxed(&usb_async_proc) != NULL) { kpreempt_disable(); softint_schedule(usb_async_sih); kpreempt_enable(); @@ -1331,7 +1329,7 @@ usb_async_intr(void *cookie) proc_t *proc; mutex_enter(&proc_lock); - if ((proc = usb_async_proc) != NULL) + if ((proc = atomic_load_relaxed(&usb_async_proc)) != NULL) psignal(proc, SIGIO); mutex_exit(&proc_lock); }