CVE-2015-3215 (C++, published 2017-06-26T15:29Z)
Description: value: The NetKVM Windows Virtio driver allows remote attackers to cause a denial of service (guest crash) via a crafted length value in an IP packet, as demonstrated by a value that does not account for the size of the IP options.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-20 \u2014 Improper Input Validation
The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
Repository: https://github.com/YanVugenfirer/kvm-guest-drivers-windows
Files changed:
NetKVM/Common/ParaNdis-Common.cpp
NetKVM/Common/ParaNdis-TX.cpp
NetKVM/Common/ndis56common.h
NetKVM/Common/sw-offload.cpp
NetKVM/wlh/ParaNdis6-Impl.cpp
Commit message: NetKVM: BZ#1169718: Checking the length only on read

Signed-off-by: Joseph Hindin <yhindin@rehat.com>


Vulnerable code:
                                            ULONG ulDataOffset)
    ppr = ParaNdis_CheckSumVerify(pPacketPages, ulPacketLength - ETH_HEADER_SIZE, ulDataOffset + ETH_HEADER_SIZE, flagsToCalculate, __FUNCTION__);
                                       GetDataLength(), __FUNCTION__);
                                pcrIpChecksum | pcrFixIPChecksum,
                                            ULONG ulDataOffset);
    return ParaNdis_CheckSumVerify(&SGBuffer, ulDataLength, 0, flags, caller);
tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket(PVOID buffer, ULONG size, LPCSTR caller);
QualifyIpPacket(IPHeader *pIpHeader, ULONG len)
        if (ipHeaderSize >= fullLength || len < fullLength)
            DPrintf(2, ("[%s] - truncated packet - ip_version %d, ipHeaderSize %d, protocol %d, iplen %d, L2 payload length %d\n", __FUNCTION__,
                ip_version, ipHeaderSize, pIpHeader->v4.ip_protocol, fullLength, len));
        if (len < fullLength)
    tTcpIpPacketParsingResult res = QualifyIpPacket(pIpHeader, ulDataLength);
tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket(PVOID buffer, ULONG size, LPCSTR caller)
    tTcpIpPacketParsingResult res = QualifyIpPacket((IPHeader *) buffer, size);
                    nBytesStripped);

Fixed code:
                                            ULONG ulDataOffset,
                                            BOOLEAN verifyLength)
    ppr = ParaNdis_CheckSumVerify(pPacketPages, ulPacketLength - ETH_HEADER_SIZE, ulDataOffset + ETH_HEADER_SIZE, flagsToCalculate,
        verifyLength, __FUNCTION__);
                                               FALSE,
                                       GetDataLength(), FALSE, __FUNCTION__);
                                pcrIpChecksum | pcrFixIPChecksum, FALSE,
                                            ULONG ulDataOffset,
                                            BOOLEAN verifyLength);
                                                BOOLEAN verifyLength,
                                                BOOLEAN verifyLength,
    return ParaNdis_CheckSumVerify(&SGBuffer, ulDataLength, 0, flags, verifyLength, caller);
tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket(PVOID buffer, ULONG size, BOOLEAN verityLength, LPCSTR caller);
QualifyIpPacket(IPHeader *pIpHeader, ULONG len, BOOLEAN verifyLength)
        if (ipHeaderSize >= fullLength || ( verifyLength && len < fullLength))
            DPrintf(2, ("[%s] - truncated packet - ip_version %d, ipHeaderSize %d, protocol %d, iplen %d, L2 payload length %d, verify = %s\n", __FUNCTION__,
                ip_version, ipHeaderSize, pIpHeader->v4.ip_protocol, fullLength, len, (verifyLength ? "true" : "false")));

        if (verifyLength && (len < fullLength))
                                                BOOLEAN verifyLength,
    tTcpIpPacketParsingResult res = QualifyIpPacket(pIpHeader, ulDataLength, verifyLength);
tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket(PVOID buffer, ULONG size, BOOLEAN verifyLength, LPCSTR caller)
    tTcpIpPacketParsingResult res = QualifyIpPacket((IPHeader *) buffer, size, verifyLength);
                    nBytesStripped, TRUE);