Bug 2453014 (CVE-2026-5164)

Summary: CVE-2026-5164 virtio-win: virtio-win: Denial of Service via unvalidated descriptor count in unmap request
Product: [Other] Security Response Reporter: OSIDB Bzimport <bzimport>
Component: vulnerabilityAssignee: Product Security <prodsec-ir-bot>
Status: NEW --- QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: unspecifiedKeywords: Security
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
A flaw was found in virtio-win. The `RhelDoUnMap()` function does not properly validate the number of descriptors provided by a user during an unmap request. A local user could exploit this input validation vulnerability by supplying an excessive number of descriptors, leading to a buffer overrun. This can cause a system crash, resulting in a Denial of Service (DoS).
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description OSIDB Bzimport 2026-03-30 14:44:30 UTC
adaptExt->blk_discard is limited to 16 descriptors, but RhelDoUnMap() never validates the number of descriptors it writes to the array. This is wrong for two separate reasons:

MAX_DISCARD_SEGMENTS is 256, so we may in theory even advertise support for a lot more segments than can actually fit in the array and even well behaving applications could trigger an overrun. (This is mostly theoretical because QEMU's virtio-blk implementation advertises 1 currently.)

The other reason is that BlockDescrCount is taken from a user buffer and has never been validated, so it can exceed the advertised maximum. I reproduced the problem by issuing an unmap request with 1024 descriptors and got an immediate BSOD. RhelDoUnMap() must explicitly validate the number of descriptors.

Use MAX_DISCARD_SEGMENTS as the size of adaptExt->blk_discard to make sure the advertised maximum is actually supported; advertise the full range instead of limiting to MAX_DISCARD_SEGMENTS - 1. Reduce MAX_DISCARD_SEGMENTS to 16 to avoid increasing the array size. And finally check first that the user buffer is even large enough that we can safely access blockDescrDataLength in it.