Commit 381d34e3 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Martin K. Petersen

scsi: megaraid_sas: Check user-provided offsets

It sounds unwise to let user space pass an unchecked 32-bit offset into a
kernel structure in an ioctl. This is an unsigned variable, so checking the
upper bound for the size of the structure it points into is sufficient to
avoid data corruption, but as the pointer might also be unaligned, it has
to be written carefully as well.

While I stumbled over this problem by reading the code, I did not continue
checking the function for further problems like it.

Link: https://lore.kernel.org/r/20201030164450.1253641-2-arnd@kernel.org
Fixes: c4a3e0a5 ("[SCSI] MegaRAID SAS RAID: new driver")
Cc: <stable@vger.kernel.org> # v2.6.15+
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 07705421
...@@ -8134,7 +8134,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, ...@@ -8134,7 +8134,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
int error = 0, i; int error = 0, i;
void *sense = NULL; void *sense = NULL;
dma_addr_t sense_handle; dma_addr_t sense_handle;
unsigned long *sense_ptr; void *sense_ptr;
u32 opcode = 0; u32 opcode = 0;
int ret = DCMD_SUCCESS; int ret = DCMD_SUCCESS;
...@@ -8257,6 +8257,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, ...@@ -8257,6 +8257,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
} }
if (ioc->sense_len) { if (ioc->sense_len) {
/* make sure the pointer is part of the frame */
if (ioc->sense_off >
(sizeof(union megasas_frame) - sizeof(__le64))) {
error = -EINVAL;
goto out;
}
sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len, sense = dma_alloc_coherent(&instance->pdev->dev, ioc->sense_len,
&sense_handle, GFP_KERNEL); &sense_handle, GFP_KERNEL);
if (!sense) { if (!sense) {
...@@ -8264,12 +8271,11 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, ...@@ -8264,12 +8271,11 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
goto out; goto out;
} }
sense_ptr = sense_ptr = (void *)cmd->frame + ioc->sense_off;
(unsigned long *) ((unsigned long)cmd->frame + ioc->sense_off);
if (instance->consistent_mask_64bit) if (instance->consistent_mask_64bit)
*sense_ptr = cpu_to_le64(sense_handle); put_unaligned_le64(sense_handle, sense_ptr);
else else
*sense_ptr = cpu_to_le32(sense_handle); put_unaligned_le32(sense_handle, sense_ptr);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment