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

Configure Feed

Select the types of activity you want to include in your feed.

scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory

There is a potential out-of-bounds access when using test_bit() on a single
word. The test_bit() and set_bit() functions operate on long values, and
when testing or setting a single word, they can exceed the word
boundary. KASAN detects this issue and produces a dump:

BUG: KASAN: slab-out-of-bounds in _scsih_add_device.constprop.0 (./arch/x86/include/asm/bitops.h:60 ./include/asm-generic/bitops/instrumented-atomic.h:29 drivers/scsi/mpt3sas/mpt3sas_scsih.c:7331) mpt3sas

Write of size 8 at addr ffff8881d26e3c60 by task kworker/u1536:2/2965

For full log, please look at [1].

Make the allocation at least the size of sizeof(unsigned long) so that
set_bit() and test_bit() have sufficient room for read/write operations
without overwriting unallocated memory.

[1] Link: https://lore.kernel.org/all/ZkNcALr3W3KGYYJG@gmail.com/

Fixes: c696f7b83ede ("scsi: mpt3sas: Implement device_remove_in_progress check in IOCTL path")
Cc: stable@vger.kernel.org
Suggested-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
Link: https://lore.kernel.org/r/20240605085530.499432-1-leitao@debian.org
Reviewed-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Breno Leitao and committed by
Martin K. Petersen
4254dfed 7926d51f

+19
+19
drivers/scsi/mpt3sas/mpt3sas_base.c
··· 8512 8512 ioc->pd_handles_sz = (ioc->facts.MaxDevHandle / 8); 8513 8513 if (ioc->facts.MaxDevHandle % 8) 8514 8514 ioc->pd_handles_sz++; 8515 + /* 8516 + * pd_handles_sz should have, at least, the minimal room for 8517 + * set_bit()/test_bit(), otherwise out-of-memory touch may occur. 8518 + */ 8519 + ioc->pd_handles_sz = ALIGN(ioc->pd_handles_sz, sizeof(unsigned long)); 8520 + 8515 8521 ioc->pd_handles = kzalloc(ioc->pd_handles_sz, 8516 8522 GFP_KERNEL); 8517 8523 if (!ioc->pd_handles) { ··· 8535 8529 ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8); 8536 8530 if (ioc->facts.MaxDevHandle % 8) 8537 8531 ioc->pend_os_device_add_sz++; 8532 + 8533 + /* 8534 + * pend_os_device_add_sz should have, at least, the minimal room for 8535 + * set_bit()/test_bit(), otherwise out-of-memory may occur. 8536 + */ 8537 + ioc->pend_os_device_add_sz = ALIGN(ioc->pend_os_device_add_sz, 8538 + sizeof(unsigned long)); 8538 8539 ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz, 8539 8540 GFP_KERNEL); 8540 8541 if (!ioc->pend_os_device_add) { ··· 8833 8820 if (ioc->facts.MaxDevHandle % 8) 8834 8821 pd_handles_sz++; 8835 8822 8823 + /* 8824 + * pd_handles should have, at least, the minimal room for 8825 + * set_bit()/test_bit(), otherwise out-of-memory touch may 8826 + * occur. 8827 + */ 8828 + pd_handles_sz = ALIGN(pd_handles_sz, sizeof(unsigned long)); 8836 8829 pd_handles = krealloc(ioc->pd_handles, pd_handles_sz, 8837 8830 GFP_KERNEL); 8838 8831 if (!pd_handles) {