[PATCH] scsi: 3w-9xxx: validate ioctl result buffer lengths
From: Yousef Alhouseen
Date: Tue Jun 30 2026 - 17:25:37 EST
Several management ioctls copy a fixed-size event, compatibility record,
or lock structure into the flexible data buffer without checking the
user-supplied buffer length. A short length allocates too little
coherent memory and lets the fixed-size copy write past the allocation.
Determine the minimum data length for each fixed-result command before
allocating the ioctl buffer and reject undersized requests.
Signed-off-by: Yousef Alhouseen <alhouseenyousef@xxxxxxxxx>
---
drivers/scsi/3w-9xxx.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 9b93a2440af8..b8a0b8410a39 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -642,6 +642,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
unsigned long *cpu_addr, data_buffer_length_adjusted = 0, flags = 0;
dma_addr_t dma_handle;
int request_id = 0;
+ size_t min_buffer_length = 0;
unsigned int sequence_id = 0;
unsigned char event_index, start_index;
TW_Ioctl_Driver_Command driver_command;
@@ -673,6 +674,26 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long
goto out2;
}
+ switch (cmd) {
+ case TW_IOCTL_GET_COMPATIBILITY_INFO:
+ min_buffer_length = sizeof(TW_Compatibility_Info);
+ break;
+ case TW_IOCTL_GET_LAST_EVENT:
+ case TW_IOCTL_GET_FIRST_EVENT:
+ case TW_IOCTL_GET_NEXT_EVENT:
+ case TW_IOCTL_GET_PREVIOUS_EVENT:
+ min_buffer_length = sizeof(TW_Event);
+ break;
+ case TW_IOCTL_GET_LOCK:
+ min_buffer_length = sizeof(TW_Lock);
+ break;
+ }
+
+ if (driver_command.buffer_length < min_buffer_length) {
+ retval = TW_IOCTL_ERROR_OS_EINVAL;
+ goto out2;
+ }
+
/* Hardware can only do multiple of 512 byte transfers */
data_buffer_length_adjusted = (driver_command.buffer_length + 511) & ~511;
@@ -2302,4 +2323,3 @@ static void __exit twa_exit(void)
module_init(twa_init);
module_exit(twa_exit);
-
--
2.55.0