diff options
author | Maor Gottlieb <maorg@mellanox.com> | 2017-08-16 11:57:04 -0400 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2017-08-16 12:53:15 -0400 |
commit | 870201f95fcbd19538aef630393fe9d583eff82e (patch) | |
tree | 4d465d12776a4ee8f8f7ae1af7f03e3535d499b4 | |
parent | 06f8174a97822f6befd28fc2dd315b43b82c700f (diff) |
IB/uverbs: Fix NULL pointer dereference during device removal
As part of ib_uverbs_remove_one which might be triggered upon
reset flow, we trigger IB_EVENT_DEVICE_FATAL event to userspace
application.
If device was removed after uverbs fd was opened but before
ib_uverbs_get_context was called, the event file will be accessed
before it was allocated, result in NULL pointer dereference:
[ 72.325873] BUG: unable to handle kernel NULL pointer dereference at (null)
...
[ 72.325984] IP: _raw_spin_lock_irqsave+0x22/0x40
[ 72.327123] Call Trace:
[ 72.327168] ib_uverbs_async_handler.isra.8+0x2e/0x160 [ib_uverbs]
[ 72.327216] ? synchronize_srcu_expedited+0x27/0x30
[ 72.327269] ib_uverbs_remove_one+0x120/0x2c0 [ib_uverbs]
[ 72.327330] ib_unregister_device+0xd0/0x180 [ib_core]
[ 72.327373] mlx5_ib_remove+0x74/0x140 [mlx5_ib]
[ 72.327422] mlx5_remove_device+0xfb/0x110 [mlx5_core]
[ 72.327466] mlx5_unregister_interface+0x3c/0xa0 [mlx5_core]
[ 72.327509] mlx5_ib_cleanup+0x10/0x962 [mlx5_ib]
[ 72.327546] SyS_delete_module+0x155/0x230
[ 72.328472] ? exit_to_usermode_loop+0x70/0xa6
[ 72.329370] do_syscall_64+0x54/0xc0
[ 72.330262] entry_SYSCALL64_slow_path+0x25/0x25
Fix it by checking that user context was allocated before
trigger the event.
Fixes: 036b10635739 ('IB/uverbs: Enable device removal when there are active user space applications')
Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
Reviewed-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index c023e2c81b8f..5e530d2bee44 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -1153,7 +1153,6 @@ static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev, | |||
1153 | kref_get(&file->ref); | 1153 | kref_get(&file->ref); |
1154 | mutex_unlock(&uverbs_dev->lists_mutex); | 1154 | mutex_unlock(&uverbs_dev->lists_mutex); |
1155 | 1155 | ||
1156 | ib_uverbs_event_handler(&file->event_handler, &event); | ||
1157 | 1156 | ||
1158 | mutex_lock(&file->cleanup_mutex); | 1157 | mutex_lock(&file->cleanup_mutex); |
1159 | ucontext = file->ucontext; | 1158 | ucontext = file->ucontext; |
@@ -1170,6 +1169,7 @@ static void ib_uverbs_free_hw_resources(struct ib_uverbs_device *uverbs_dev, | |||
1170 | * for example due to freeing the resources | 1169 | * for example due to freeing the resources |
1171 | * (e.g mmput). | 1170 | * (e.g mmput). |
1172 | */ | 1171 | */ |
1172 | ib_uverbs_event_handler(&file->event_handler, &event); | ||
1173 | ib_dev->disassociate_ucontext(ucontext); | 1173 | ib_dev->disassociate_ucontext(ucontext); |
1174 | mutex_lock(&file->cleanup_mutex); | 1174 | mutex_lock(&file->cleanup_mutex); |
1175 | ib_uverbs_cleanup_ucontext(file, ucontext, true); | 1175 | ib_uverbs_cleanup_ucontext(file, ucontext, true); |