Skip to content

Commit

Permalink
Fix buffer overrun in viostor when VM is configured to have
Browse files Browse the repository at this point in the history
more disk queues than number of CPUs.

The memory buffer length viostor allocates to store the group
affinity mask is based on the num_queues but the last redirection
message number is based on msix_vectors. If msix_vectors is greater
than num_queues, storport will write beyond the end of the allocated
buffer which causes non-paged pool corruption. This change fixes
the explained problem.

1. Set last redirection message number based on num_queues in viostor.
2. Add a field num_affinity in ADAPTER_EXTENSION to store the group
affinity array length.
3. Add assertion in viostor to ensure that last redirection
message number is less than num_affinity.

Signed-off-by: Hao Xiang <[email protected]>
  • Loading branch information
haoxiangbd authored and vrozenfe committed Jul 26, 2022
1 parent f0e12a9 commit 16e7da6
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 2 deletions.
6 changes: 4 additions & 2 deletions viostor/virtio_stor.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,9 +572,10 @@ VirtIoFindAdapter(
RhelDbgPrint(TRACE_LEVEL_INFORMATION, " Pool area at %p, size = %d\n", adaptExt->poolAllocationVa, adaptExt->poolAllocationSize);
RhelDbgPrint(TRACE_LEVEL_INFORMATION, " pmsg_affinity = %p\n",adaptExt->pmsg_affinity);
if (!adaptExt->dump_mode && (adaptExt->num_queues > 1) && (adaptExt->pmsg_affinity == NULL)) {
adaptExt->num_affinity = adaptExt->num_queues + 1;
ULONG Status =
StorPortAllocatePool(DeviceExtension,
sizeof(GROUP_AFFINITY) * ((ULONGLONG)adaptExt->num_queues + 1),
sizeof(GROUP_AFFINITY) * (ULONGLONG)adaptExt->num_affinity,
VIOBLK_POOL_TAG,
(PVOID*)&adaptExt->pmsg_affinity);
RhelDbgPrint(TRACE_LEVEL_FATAL, " pmsg_affinity = %p Status = %lu\n",adaptExt->pmsg_affinity, Status);
Expand Down Expand Up @@ -791,7 +792,8 @@ VirtIoHwInitialize(
if (CHECKFLAG(perfData.Flags, STOR_PERF_INTERRUPT_MESSAGE_RANGES)) {
adaptExt->perfFlags |= STOR_PERF_INTERRUPT_MESSAGE_RANGES;
perfData.FirstRedirectionMessageNumber = 1;
perfData.LastRedirectionMessageNumber = adaptExt->msix_vectors - 1;
perfData.LastRedirectionMessageNumber = perfData.FirstRedirectionMessageNumber + adaptExt->num_queues - 1;
ASSERT(perfData.lastRedirectionMessageNumber < adaptExt->num_affinity);
}
if (CHECKFLAG(perfData.Flags, STOR_PERF_CONCURRENT_CHANNELS)) {
adaptExt->perfFlags |= STOR_PERF_CONCURRENT_CHANNELS;
Expand Down
1 change: 1 addition & 0 deletions viostor/virtio_stor.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ typedef struct _ADAPTER_EXTENSION {
BOOLEAN removed;
ULONG max_tx_length;
PGROUP_AFFINITY pmsg_affinity;
ULONG num_affinity;
STOR_ADDR_BTL8 device_address;
blk_discard_write_zeroes blk_discard[16];
REQUEST_LIST processing_srbs[MAX_CPU];
Expand Down

0 comments on commit 16e7da6

Please sign in to comment.