RHELMISC-30350: [virtio-win] Add scsi-filter to upstream repository#1562
RHELMISC-30350: [virtio-win] Add scsi-filter to upstream repository#1562marekkedzierski wants to merge 1 commit intovirtio-win:masterfrom
Conversation
This commit introduces the StorSplitter-Filter driver to handle storage splitting. Signed-off-by: Marek Kedzierski <mkedzier@redhat.com>
There was a problem hiding this comment.
Code Review
This pull request implements StorSplitter, a WDF storage filter driver that intercepts and splits large I/O requests to match hardware transfer limits, accompanied by a user-mode control application. The review identified critical bugs in the SCSI pass-through logic, including the use of a non-existent structure member and an uninitialized data buffer pointer. Additionally, a potential integer overflow was noted in the calculation of safe transfer sizes.
| spt.DataIn = SCSI_IOCTL_DATA_IN; | ||
| spt.DataTransferLength = sizeof(CUSTOM_VPD_BLOCK_LIMITS_PAGE); | ||
| spt.TimeOutValue = 2; | ||
| spt.DataBufferOffset = sizeof(SCSI_PASS_THROUGH); |
There was a problem hiding this comment.
| target, NULL, IOCTL_SCSI_PASS_THROUGH, | ||
| &inputDescriptor, &outputDescriptor, NULL, NULL | ||
| ); |
There was a problem hiding this comment.
When sending IOCTL_SCSI_PASS_THROUGH from a kernel driver, the DataBuffer field in the SCSI_PASS_THROUGH structure must be initialized to a valid kernel-mode address where the data should be transferred. Since you are using a single allocated buffer for both the header and the data, you should set DataBuffer to point to the memory immediately following the header within that buffer.
PSCSI_PASS_THROUGH pSptInBuffer = (PSCSI_PASS_THROUGH)buffer;
pSptInBuffer->DataBuffer = (PVOID)(buffer + sizeof(SCSI_PASS_THROUGH));
status = WdfIoTargetSendIoctlSynchronously(
target, NULL, IOCTL_SCSI_PASS_THROUGH,
&inputDescriptor, &outputDescriptor, NULL, NULL
);| if (maxTransferBlocks > 0) | ||
| { | ||
| // Use dynamically retrieved logical sector size instead of hardcoded 512 | ||
| ULONG maxBytes = maxTransferBlocks * devCtx->SectorSize; |
There was a problem hiding this comment.
Potential integer overflow. maxTransferBlocks is a 32-bit value and devCtx->SectorSize is typically 512 or 4096. Their product can exceed the range of a 32-bit ULONG (4GB) if the hardware reports a very large maximum transfer length. Since MaxSafeTransferSizeBytes is a size_t, you should perform the multiplication using 64-bit integers on 64-bit systems.
size_t maxBytes = (size_t)maxTransferBlocks * devCtx->SectorSize;
This commit introduces the StorSplitter-Filter driver to handle storage splitting.