diff options
| author | Thorsten Blum <thorsten.blum@linux.dev> | 2025-09-19 11:26:37 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-10-19 16:33:53 +0200 |
| commit | 7b2ef1a0a2f15a9579e0a0ec61877b56a05269b7 (patch) | |
| tree | aa79ad040433fe7ef1af0a80de7981c7dd5aa710 /drivers | |
| parent | 305b1a39f3bb27a8c13bab43931af6b23612c3ed (diff) | |
| download | linux-7b2ef1a0a2f15a9579e0a0ec61877b56a05269b7.tar.gz linux-7b2ef1a0a2f15a9579e0a0ec61877b56a05269b7.tar.bz2 linux-7b2ef1a0a2f15a9579e0a0ec61877b56a05269b7.zip | |
scsi: hpsa: Fix potential memory leak in hpsa_big_passthru_ioctl()
commit b81296591c567b12d3873b05a37b975707959b94 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/scsi/hpsa.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 0c49414c1f35..6cb6586f4790 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -6528,18 +6528,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++; |
