Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: megaraid_mm: Fix end of loop tests for list_for_each_entry()

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>

authored by

Harshvardhan Jha and committed by
Martin K. Petersen
77541f78 d712d3fb

+15 -6
+15 -6
drivers/scsi/megaraid/megaraid_mm.c
··· 238 238 mimd_t mimd; 239 239 uint32_t adapno; 240 240 int iterator; 241 - 241 + bool is_found; 242 242 243 243 if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) { 244 244 *rval = -EFAULT; ··· 254 254 255 255 adapter = NULL; 256 256 iterator = 0; 257 + is_found = false; 257 258 258 259 list_for_each_entry(adapter, &adapters_list_g, list) { 259 - if (iterator++ == adapno) break; 260 + if (iterator++ == adapno) { 261 + is_found = true; 262 + break; 263 + } 260 264 } 261 265 262 - if (!adapter) { 266 + if (!is_found) { 263 267 *rval = -ENODEV; 264 268 return NULL; 265 269 } ··· 729 725 uint32_t adapno; 730 726 int iterator; 731 727 mraid_mmadp_t* adapter; 728 + bool is_found; 732 729 733 730 /* 734 731 * When the kioc returns from driver, make sure it still doesn't ··· 752 747 iterator = 0; 753 748 adapter = NULL; 754 749 adapno = kioc->adapno; 750 + is_found = false; 755 751 756 752 con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed " 757 753 "ioctl that was timedout before\n")); 758 754 759 755 list_for_each_entry(adapter, &adapters_list_g, list) { 760 - if (iterator++ == adapno) break; 756 + if (iterator++ == adapno) { 757 + is_found = true; 758 + break; 759 + } 761 760 } 762 761 763 762 kioc->timedout = 0; 764 763 765 - if (adapter) { 764 + if (is_found) 766 765 mraid_mm_dealloc_kioc( adapter, kioc ); 767 - } 766 + 768 767 } 769 768 else { 770 769 wake_up(&wait_q);