IB/srp: Avoid that duplicate responses trigger a kernel bug
authorBart Van Assche <bart.vanassche@sandisk.com>
Tue, 14 Feb 2017 18:56:30 +0000 (10:56 -0800)
committerDoug Ledford <dledford@redhat.com>
Sun, 19 Feb 2017 14:51:52 +0000 (09:51 -0500)
After srp_process_rsp() returns there is a short time during which
the scsi_host_find_tag() call will return a pointer to the SCSI
command that is being completed. If during that time a duplicate
response is received, avoid that the following call stack appears:

BUG: unable to handle kernel NULL pointer dereference at           (null)
IP: srp_recv_done+0x450/0x6b0 [ib_srp]
Oops: 0000 [#1] SMP
CPU: 10 PID: 0 Comm: swapper/10 Not tainted 4.10.0-rc7-dbg+ #1
Call Trace:
 <IRQ>
 __ib_process_cq+0x4b/0xd0 [ib_core]
 ib_poll_handler+0x1d/0x70 [ib_core]
 irq_poll_softirq+0xba/0x120
 __do_softirq+0xba/0x4c0
 irq_exit+0xbe/0xd0
 smp_apic_timer_interrupt+0x38/0x50
 apic_timer_interrupt+0x90/0xa0
 </IRQ>
RIP: srp_recv_done+0x450/0x6b0 [ib_srp] RSP: ffff88046f483e20

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Israel Rukshin <israelr@mellanox.com>
Cc: Max Gurtovoy <maxg@mellanox.com>
Cc: Laurence Oberman <loberman@redhat.com>
Cc: Steve Feeley <Steve.Feeley@sandisk.com>
Cc: <stable@vger.kernel.org>
Reviewed-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/ulp/srp/ib_srp.c

index 6e4467150049365c2bad34b9e2a1bd37692f552d..a49289f600b1b7d4b7f7a584973e05e6386a2856 100644 (file)
@@ -1892,9 +1892,11 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp)
                complete(&ch->tsk_mgmt_done);
        } else {
                scmnd = scsi_host_find_tag(target->scsi_host, rsp->tag);
-               if (scmnd) {
+               if (scmnd && scmnd->host_scribble) {
                        req = (void *)scmnd->host_scribble;
                        scmnd = srp_claim_req(ch, req, NULL, scmnd);
+               } else {
+                       scmnd = NULL;
                }
                if (!scmnd) {
                        shost_printk(KERN_ERR, target->scsi_host,