summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorsten Blum <thorsten.blum@linux.dev>2025-09-19 11:26:37 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2025-09-24 21:27:00 -0400
commitb81296591c567b12d3873b05a37b975707959b94 (patch)
tree5213adc2a32e52798d3642fa52e4018400c53bc6
parent88e8acffd7af9b030d2772f27ee30639be7024cf (diff)
scsi: hpsa: Fix potential memory leak in hpsa_big_passthru_ioctl()
Replace kmalloc() followed by copy_from_user() with memdup_user() to fix a memory leak that occurs when copy_from_user(buff[sg_used],,) fails and the 'cleanup1:' path does not free the memory for 'buff[sg_used]'. Using memdup_user() avoids this by freeing the memory internally. Since memdup_user() already allocates memory, use kzalloc() in the else branch instead of manually zeroing 'buff[sg_used]' using memset(0). Cc: stable@vger.kernel.org Fixes: edd163687ea5 ("[SCSI] hpsa: add driver for HP Smart Array controllers.") Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Acked-by: Don Brace <don.brace@microchip.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/hpsa.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 8738ad757235..1f917e882ae4 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -6517,18 +6517,21 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h,
while (left) {
sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
buff_size[sg_used] = sz;
- buff[sg_used] = kmalloc(sz, GFP_KERNEL);
- if (buff[sg_used] == NULL) {
- status = -ENOMEM;
- goto cleanup1;
- }
+
if (ioc->Request.Type.Direction & XFER_WRITE) {
- if (copy_from_user(buff[sg_used], data_ptr, sz)) {
- status = -EFAULT;
+ buff[sg_used] = memdup_user(data_ptr, sz);
+ if (IS_ERR(buff[sg_used])) {
+ status = PTR_ERR(buff[sg_used]);
goto cleanup1;
}
- } else
- memset(buff[sg_used], 0, sz);
+ } else {
+ buff[sg_used] = kzalloc(sz, GFP_KERNEL);
+ if (!buff[sg_used]) {
+ status = -ENOMEM;
+ goto cleanup1;
+ }
+ }
+
left -= sz;
data_ptr += sz;
sg_used++;