aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/uverbs.h
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2016-07-03 15:28:18 +0300
committerDoug Ledford <dledford@redhat.com>2016-08-03 21:03:36 -0400
commitd1e09f304a1d9651c5059ebfeb696dc2effc9b32 (patch)
treeb846d3f079fc4953fecf69ce98d4ab29e0061db8 /drivers/infiniband/core/uverbs.h
parentIB/mthca: Clean up error unwind flow in mthca_reset() (diff)
downloadlinux-dev-d1e09f304a1d9651c5059ebfeb696dc2effc9b32.tar.xz
linux-dev-d1e09f304a1d9651c5059ebfeb696dc2effc9b32.zip
IB/uverbs: Fix race between uverbs_close and remove_one
Fixes an oops that might happen if uverbs_close races with remove_one. Both contexts may run ib_uverbs_cleanup_ucontext, it depends on the flow. Currently, there is no protection for a case that remove_one didn't make the cleanup it runs to its end, the underlying ib_device was freed then uverbs_close will call ib_uverbs_cleanup_ucontext and OOPs. Above might happen if uverbs_close deleted the file from the list then remove_one didn't find it and runs to its end. Fixes to protect against that case by a new cleanup lock so that ib_uverbs_cleanup_ucontext will be called always before that remove_one is ended. Fixes: 35d4a0b63dc0 ("IB/uverbs: Fix race between ib_uverbs_open and remove_one") Reported-by: Devesh Sharma <devesh.sharma@broadcom.com> Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Leon Romanovsky <leon@kernel.org> Signed-off-by: Doug Ledford <dledford@redhat.com>
Diffstat (limited to 'drivers/infiniband/core/uverbs.h')
-rw-r--r--drivers/infiniband/core/uverbs.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index 612ccfd39bf9..9245e55debed 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -116,6 +116,7 @@ struct ib_uverbs_event_file {
struct ib_uverbs_file {
struct kref ref;
struct mutex mutex;
+ struct mutex cleanup_mutex; /* protect cleanup */
struct ib_uverbs_device *device;
struct ib_ucontext *ucontext;
struct ib_event_handler event_handler;