[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20230512125114.1329613-2-bigunclemax@gmail.com>
Date: Fri, 12 May 2023 15:51:13 +0300
From: Maksim Kiselev <bigunclemax@...il.com>
To: Adaptec OEM Raid Solutions <aacraid@...rosemi.com>
Cc: Maksim Kiselev <bigunclemax@...il.com>,
"James E.J. Bottomley" <jejb@...ux.ibm.com>,
"Martin K. Petersen" <martin.petersen@...cle.com>,
linux-scsi@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH 1/1] scsi: aacraid: Prevent stopping of already finished thread on adapter reset
For some reason `aac_adapter_check_health` may fail what leads to
`aac_command_thread` finish. After that if `scsi_try_host_reset` happens,
it leads to access to 'aac->thread->pid' and attempt to stop already
finished thread (`kthread_stop(aac->thread`). As a result we have
use-after-free warning and NULL pointer dereference crash.
This patch should prevent access to already finished thread.
[ 461.707724] ------------[ cut here ]------------
[ 461.707725] refcount_t: addition on 0; use-after-free.
[ 461.707729] WARNING: CPU: 1 PID: 116 at lib/refcount.c:25 refcount_warn_saturate+0x72/0x100
[ 461.707783] CPU: 1 PID: 116 Comm: scsi_eh_0 Tainted: G W 6.3.0.0-g2cd293ea6f73-dirty #12
[ 461.707785] Hardware name: Supermicro Super Server/X11SSH-LN4F, BIOS 2.7 12/07/2021
[ 461.707786] RIP: 0010:refcount_warn_saturate+0x72/0x100
[ 461.707804] Call Trace:
[ 461.707805] <TASK>
[ 461.707806] kthread_stop+0xdb/0xe0
[ 461.707809] aac_reset_adapter+0x409/0x6f0 [aacraid]
[ 461.707815] aac_eh_host_reset+0x50/0x90 [aacraid]
[ 461.707819] scsi_try_host_reset+0x26/0xc0 [scsi_mod]
[ 461.707825] scsi_eh_ready_devs+0x34e/0x920 [scsi_mod]
[ 461.707831] ? scsi_eh_get_sense+0x160/0x160 [scsi_mod]
[ 461.707838] scsi_error_handler+0x355/0x360 [scsi_mod]
[ 461.707845] kthread+0xda/0x100
[ 461.707847] ? kthread_complete_and_exit+0x20/0x20
[ 461.707849] ret_from_fork+0x1f/0x30
[ 461.707852] </TASK>
[ 461.707852] ---[ end trace 0000000000000000 ]---
[ 461.707855] BUG: kernel NULL pointer dereference, address: 0000000000000000
[ 461.708215] #PF: supervisor write access in kernel mode
[ 461.708552] #PF: error_code(0x0002) - not-present page
[ 461.708900] PGD 0 P4D 0
[ 461.709234] Oops: 0002 [#1] PREEMPT SMP
[ 461.709558] CPU: 1 PID: 116 Comm: scsi_eh_0 Tainted: G W 6.3.0.0-g2cd293ea6f73-dirty #12
[ 461.710521] RIP: 0010:kthread_stop+0x3f/0xe0
[ 461.715884] Call Trace:
[ 461.716267] <TASK>
[ 461.716651] aac_reset_adapter+0x409/0x6f0 [aacraid]
[ 461.717052] aac_eh_host_reset+0x50/0x90 [aacraid]
[ 461.717455] scsi_try_host_reset+0x26/0xc0 [scsi_mod]
[ 461.717856] scsi_eh_ready_devs+0x34e/0x920 [scsi_mod]
[ 461.718262] ? scsi_eh_get_sense+0x160/0x160 [scsi_mod]
[ 461.718656] scsi_error_handler+0x355/0x360 [scsi_mod]
[ 461.719044] kthread+0xda/0x100
[ 461.719429] ? kthread_complete_and_exit+0x20/0x20
[ 461.719823] ret_from_fork+0x1f/0x30
[ 461.720216] </TASK>
[ 461.724589] CR2: 0000000000000000
[ 461.725038] ---[ end trace 0000000000000000 ]---
[ 461.732223] note: scsi_eh_0[116] exited with irqs disabled
Signed-off-by: Maksim Kiselev <bigunclemax@...il.com>
---
drivers/scsi/aacraid/commsup.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index deb32c9f4b3e..9f253a360e9f 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1494,9 +1494,10 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
* commands are completing in the interrupt service.
*/
aac_adapter_disable_int(aac);
- if (aac->thread && aac->thread->pid != current->pid) {
+ if (!aac->aif_thread || (aac->thread && aac->thread->pid != current->pid)) {
spin_unlock_irq(host->host_lock);
- kthread_stop(aac->thread);
+ if (aac->aif_thread)
+ kthread_stop(aac->thread);
aac->thread = NULL;
jafo = 1;
}
--
2.39.2
Powered by blists - more mailing lists