Message ID | 20231016101749.5059-1-njavali@marvell.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | qla2xxx: Fix double free of dsd_list during driver load. | expand |
On Mon, 16 Oct 2023 15:47:49 +0530, Nilesh Javali wrote: > On driver load, scsi_add_host can fail. This trigger the free path > to call qla2x00_mem_free() multiple times. This cause Null pointer > access of ha->base_qpair. Add check before access to free. > > BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 > IP: [<ffffffffc118f73c>] qla2x00_mem_free+0x51c/0xcb0 [qla2xxx] > PGD 8000001fcfe4a067 PUD 1fc8f0a067 PMD 0 > Oops: 0000 [#1] SMP > RIP: 0010:[<ffffffffc118f73c>] [<ffffffffc118f73c>] qla2x00_mem_free+0x51c/0xcb0 [qla2xxx] > RSP: 0018:ffff8ace97a93a30 EFLAGS: 00010246 > RAX: 0000000000000000 RBX: ffff8ace8efd0000 RCX: 000000000000488f > RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 > RBP: ffff8ace97a93a60 R08: 000000000001f040 R09: ffffffff8678209b > R10: ffff8acf7d6df040 R11: ffffc591c0fcc980 R12: ffffffff87034800 > R13: ffff8acf0e3cc740 R14: ffff8ace8efd0000 R15: 00000000fffffff4 > FS: 00007f4cf5449740(0000) GS:ffff8acf7d6c0000(0000) knlGS:0000000000000000 > CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > CR2: 0000000000000030 CR3: 0000001fc2f6c000 CR4: 00000000007607e0 > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 > DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 > Call Trace: > [<ffffffff86781f18>] ? kobject_put+0x28/0x60 > [<ffffffffc119a59c>] qla2x00_probe_one+0x19fc/0x3040 [qla2xxx] > > [...] Applied to 6.6/scsi-fixes, thanks! [1/1] qla2xxx: Fix double free of dsd_list during driver load. https://git.kernel.org/mkp/scsi/c/097c06394c83
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 50db08265c51..dcae09a37d49 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4953,7 +4953,7 @@ qla2x00_mem_free(struct qla_hw_data *ha) ha->gid_list = NULL; ha->gid_list_dma = 0; - if (!list_empty(&ha->base_qpair->dsd_list)) { + if (ha->base_qpair && !list_empty(&ha->base_qpair->dsd_list)) { struct dsd_dma *dsd_ptr, *tdsd_ptr; /* clean up allocated prev pool */