Skip to content

RHELMISC-30350: [virtio-win] Add scsi-filter to upstream repository#1562

Open
marekkedzierski wants to merge 1 commit intovirtio-win:masterfrom
marekkedzierski:add-storsplitter-filter
Open

RHELMISC-30350: [virtio-win] Add scsi-filter to upstream repository#1562
marekkedzierski wants to merge 1 commit intovirtio-win:masterfrom
marekkedzierski:add-storsplitter-filter

Conversation

@marekkedzierski
Copy link
Copy Markdown

This commit introduces the StorSplitter-Filter driver to handle storage splitting.

This commit introduces the StorSplitter-Filter driver to handle storage splitting.

Signed-off-by: Marek Kedzierski <mkedzier@redhat.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The SCSI_PASS_THROUGH structure does not contain a member named DataBufferOffset. This will cause a compilation error. This member exists in SCSI_PASS_THROUGH_EX, but you are using the non-EX version. For SCSI_PASS_THROUGH, you must use the DataBuffer pointer field.

Comment on lines +283 to +285
target, NULL, IOCTL_SCSI_PASS_THROUGH,
&inputDescriptor, &outputDescriptor, NULL, NULL
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants