RDMA/srpt: Fix a use-after-free in the channel release code
This patch avoids that KASAN sporadically reports the following: BUG: KASAN: use-after-free in rxe_run_task+0x1e/0x60 [rdma_rxe] Read of size 1 at addr ffff88801c50d8f4 by task check/24830 CPU: 4 PID: 24830 Comm: check Not tainted 4.20.0-rc6-dbg+ #3 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 Call Trace: dump_stack+0x86/0xca print_address_description+0x71/0x239 kasan_report.cold.5+0x242/0x301 __asan_load1+0x47/0x50 rxe_run_task+0x1e/0x60 [rdma_rxe] rxe_post_send+0x4bd/0x8d0 [rdma_rxe] srpt_zerolength_write+0xe1/0x160 [ib_srpt] srpt_close_ch+0x8b/0xe0 [ib_srpt] srpt_set_enabled+0xe7/0x150 [ib_srpt] srpt_tpg_enable_store+0xc0/0x100 [ib_srpt] configfs_write_file+0x157/0x1d0 __vfs_write+0xd7/0x3d0 vfs_write+0x102/0x290 ksys_write+0xab/0x130 __x64_sys_write+0x43/0x50 do_syscall_64+0x71/0x210 entry_SYSCALL_64_after_hwframe+0x49/0xbe Allocated by task 13856: save_stack+0x43/0xd0 kasan_kmalloc+0xc7/0xe0 kasan_slab_alloc+0x11/0x20 kmem_cache_alloc+0x105/0x320 rxe_alloc+0xff/0x1f0 [rdma_rxe] rxe_create_qp+0x9f/0x160 [rdma_rxe] ib_create_qp+0xf5/0x690 [ib_core] rdma_create_qp+0x6a/0x140 [rdma_cm] srpt_cm_req_recv.cold.59+0x1588/0x237b [ib_srpt] srpt_rdma_cm_req_recv.isra.35+0x1d5/0x220 [ib_srpt] srpt_rdma_cm_handler+0x6f/0x100 [ib_srpt] cma_listen_handler+0x59/0x60 [rdma_cm] cma_ib_req_handler+0xd5b/0x2570 [rdma_cm] cm_process_work+0x2e/0x110 [ib_cm] cm_work_handler+0x2aae/0x502b [ib_cm] process_one_work+0x481/0x9e0 worker_thread+0x67/0x5b0 kthread+0x1cf/0x1f0 ret_from_fork+0x24/0x30 Freed by task 3440: save_stack+0x43/0xd0 __kasan_slab_free+0x139/0x190 kasan_slab_free+0xe/0x10 kmem_cache_free+0xbc/0x330 rxe_elem_release+0x66/0xe0 [rdma_rxe] rxe_destroy_qp+0x3f/0x50 [rdma_rxe] ib_destroy_qp+0x140/0x360 [ib_core] srpt_release_channel_work+0xdc/0x310 [ib_srpt] process_one_work+0x481/0x9e0 worker_thread+0x67/0x5b0 kthread+0x1cf/0x1f0 ret_from_fork+0x24/0x30 Cc: Sergey Gorenko <sergeygo@mellanox.com> Cc: Max Gurtovoy <maxg@mellanox.com> Cc: Laurence Oberman <loberman@redhat.com> Cc: <stable@vger.kernel.org> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
882981f4a4
commit
ed041919f0
|
@ -2010,6 +2010,14 @@ static void srpt_free_ch(struct kref *kref)
|
|||
kfree_rcu(ch, rcu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Shut down the SCSI target session, tell the connection manager to
|
||||
* disconnect the associated RDMA channel, transition the QP to the error
|
||||
* state and remove the channel from the channel list. This function is
|
||||
* typically called from inside srpt_zerolength_write_done(). Concurrent
|
||||
* srpt_zerolength_write() calls from inside srpt_close_ch() are possible
|
||||
* as long as the channel is on sport->nexus_list.
|
||||
*/
|
||||
static void srpt_release_channel_work(struct work_struct *w)
|
||||
{
|
||||
struct srpt_rdma_ch *ch;
|
||||
|
@ -2037,6 +2045,11 @@ static void srpt_release_channel_work(struct work_struct *w)
|
|||
else
|
||||
ib_destroy_cm_id(ch->ib_cm.cm_id);
|
||||
|
||||
sport = ch->sport;
|
||||
mutex_lock(&sport->mutex);
|
||||
list_del_rcu(&ch->list);
|
||||
mutex_unlock(&sport->mutex);
|
||||
|
||||
srpt_destroy_ch_ib(ch);
|
||||
|
||||
srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring,
|
||||
|
@ -2047,11 +2060,6 @@ static void srpt_release_channel_work(struct work_struct *w)
|
|||
sdev, ch->rq_size,
|
||||
srp_max_req_size, DMA_FROM_DEVICE);
|
||||
|
||||
sport = ch->sport;
|
||||
mutex_lock(&sport->mutex);
|
||||
list_del_rcu(&ch->list);
|
||||
mutex_unlock(&sport->mutex);
|
||||
|
||||
wake_up(&sport->ch_releaseQ);
|
||||
|
||||
kref_put(&ch->kref, srpt_free_ch);
|
||||
|
|
Loading…
Reference in New Issue