Skip to content

Commit

Permalink
scsi: megaraid_mm: Fix end of loop tests for list_for_each_entry()
Browse files Browse the repository at this point in the history
[ Upstream commit 77541f7 ]

The list_for_each_entry() iterator, "adapter" in this code, can never be
NULL.  If we exit the loop without finding the correct adapter then
"adapter" points invalid memory that is an offset from the list head.  This
will eventually lead to memory corruption and presumably a kernel crash.

Link: https://lore.kernel.org/r/20210708074642.23599-1-harshvardhan.jha@oracle.com
Acked-by: Sumit Saxena <sumit.saxena@broadcom.com>
Signed-off-by: Harshvardhan Jha <harshvardhan.jha@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Harshvardhan Jha authored and Sasha Levin committed Aug 26, 2021
1 parent 968ee91 commit cc312fa
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions drivers/scsi/megaraid/megaraid_mm.c
Expand Up @@ -238,7 +238,7 @@ mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)
mimd_t mimd;
uint32_t adapno;
int iterator;

bool is_found;

if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) {
*rval = -EFAULT;
Expand All @@ -254,12 +254,16 @@ mraid_mm_get_adapter(mimd_t __user *umimd, int *rval)

adapter = NULL;
iterator = 0;
is_found = false;

list_for_each_entry(adapter, &adapters_list_g, list) {
if (iterator++ == adapno) break;
if (iterator++ == adapno) {
is_found = true;
break;
}
}

if (!adapter) {
if (!is_found) {
*rval = -ENODEV;
return NULL;
}
Expand Down Expand Up @@ -725,6 +729,7 @@ ioctl_done(uioc_t *kioc)
uint32_t adapno;
int iterator;
mraid_mmadp_t* adapter;
bool is_found;

/*
* When the kioc returns from driver, make sure it still doesn't
Expand All @@ -747,19 +752,23 @@ ioctl_done(uioc_t *kioc)
iterator = 0;
adapter = NULL;
adapno = kioc->adapno;
is_found = false;

con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed "
"ioctl that was timedout before\n"));

list_for_each_entry(adapter, &adapters_list_g, list) {
if (iterator++ == adapno) break;
if (iterator++ == adapno) {
is_found = true;
break;
}
}

kioc->timedout = 0;

if (adapter) {
if (is_found)
mraid_mm_dealloc_kioc( adapter, kioc );
}

}
else {
wake_up(&wait_q);
Expand Down

0 comments on commit cc312fa

Please sign in to comment.