VirtualBox

Changeset 52627 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Sep 5, 2014 8:18:13 PM (10 years ago)
Author:
vboxsync
Message:

SUP: Fixed comctl32.dll resolving (generic winsxs) and fixed a crash log statement in LdrLoadDll when the search path is used for flags instead of an actual string pointer.

Location:
trunk/src/VBox/HostDrivers/Support/win
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h

    r52529 r52627  
    5757                                                uint32_t *pcFixes, PRTERRINFO pErrInfo);
    5858
     59DECLHIDDEN(bool)    supHardViUtf16PathIsEqualEx(PCRTUTF16 pawcLeft, size_t cwcLeft, const char *pszRight);
    5960DECLHIDDEN(bool)    supHardViUniStrPathStartsWithUniStr(UNICODE_STRING const *pUniStrLeft,
    6061                                                        UNICODE_STRING const *pUniStrRight, bool fCheckSlash);
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp

    r52600 r52627  
    473473 *
    474474 * @returns true if equal, false if not.
    475  * @param   pwszLeft            The UTF-16 path string.
     475 * @param   pawcLeft            The UTF-16 path string, not necessarily null
     476 *                              terminated.
     477 * @param   cwcLeft             The number of chars in the left string,
     478 *                              RTSTR_MAX if unknown but terminated.
    476479 * @param   pszRight            The ascii string.
    477480 */
    478 static bool supHardViUtf16PathIsEqual(PCRTUTF16 pwszLeft, const char *pszRight)
     481DECLHIDDEN(bool) supHardViUtf16PathIsEqualEx(PCRTUTF16 pawcLeft, size_t cwcLeft, const char *pszRight)
    479482{
    480483    for (;;)
    481484    {
    482         RTUTF16 wc = *pwszLeft++;
     485        RTUTF16 wc;
     486        if (cwcLeft-- > 0)
     487            wc =*pawcLeft++;
     488        else
     489            wc = 0;
    483490        uint8_t b  = *pszRight++;
    484491        if (b != wc)
     
    504511            return true;
    505512    }
     513}
     514
     515
     516/**
     517 * Simple case insensitive UTF-16 / ASCII path compare.
     518 *
     519 * @returns true if equal, false if not.
     520 * @param   pwszLeft            The UTF-16 path string.
     521 * @param   pszRight            The ascii string.
     522 */
     523static bool supHardViUtf16PathIsEqual(PCRTUTF16 pwszLeft, const char *pszRight)
     524{
     525    return supHardViUtf16PathIsEqualEx(pwszLeft, RTSTR_MAX, pszRight);
    506526}
    507527
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r52535 r52627  
    803803                RTUTF16     wszPath[260 + 260]; /* Assumes we've limited the import name length to 256. */
    804804                AssertCompile(sizeof(wszPath) > sizeof(g_System32NtPath));
    805                 struct
     805
     806                /*
     807                 * Check for DLL isolation / redirection / mapping.
     808                 */
     809                size_t      cwcName  = 260;
     810                PRTUTF16    pwszName = &wszPath[0];
     811                int rc = RTStrToUtf16Ex(pCur->szName, RTSTR_MAX, &pwszName, cwcName, &cwcName);
     812                if (RT_SUCCESS(rc))
    806813                {
    807                     PRTUTF16 pawcDir;
    808                     uint32_t cwcDir;
    809                 } Tmp, aDirs[] =
     814                    UNICODE_STRING UniStrName;
     815                    UniStrName.Buffer = wszPath;
     816                    UniStrName.Length = (USHORT)cwcName * sizeof(WCHAR);
     817                    UniStrName.MaximumLength = UniStrName.Length + sizeof(WCHAR);
     818
     819                    UNICODE_STRING UniStrStatic;
     820                    UniStrStatic.Buffer = &wszPath[cwcName + 1];
     821                    UniStrStatic.Length = 0;
     822                    UniStrStatic.MaximumLength = (USHORT)sizeof(wszPath) - UniStrStatic.MaximumLength - sizeof(WCHAR);
     823
     824                    static UNICODE_STRING const s_DefaultSuffix = RTNT_CONSTANT_UNISTR(L".dll");
     825                    UNICODE_STRING  UniStrDynamic = { 0, 0, NULL };
     826                    PUNICODE_STRING pUniStrResult = NULL;
     827
     828                    rcNt = RtlDosApplyFileIsolationRedirection_Ustr(1 /*fFlags*/,
     829                                                                    &UniStrName,
     830                                                                    (PUNICODE_STRING)&s_DefaultSuffix,
     831                                                                    &UniStrStatic,
     832                                                                    &UniStrDynamic,
     833                                                                    &pUniStrResult,
     834                                                                    NULL /*pNewFlags*/,
     835                                                                    NULL /*pcbFilename*/,
     836                                                                    NULL /*pcbNeeded*/);
     837                    if (NT_SUCCESS(rcNt))
     838                    {
     839                        IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     840                        OBJECT_ATTRIBUTES   ObjAttr;
     841                        InitializeObjectAttributes(&ObjAttr, pUniStrResult,
     842                                                   OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
     843                        rcNt = NtCreateFile(&hFile,
     844                                            FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
     845                                            &ObjAttr,
     846                                            &Ios,
     847                                            NULL /* Allocation Size*/,
     848                                            FILE_ATTRIBUTE_NORMAL,
     849                                            FILE_SHARE_READ,
     850                                            FILE_OPEN,
     851                                            FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
     852                                            NULL /*EaBuffer*/,
     853                                            0 /*EaLength*/);
     854                        if (NT_SUCCESS(rcNt))
     855                            rcNt = Ios.Status;
     856                        if (!NT_SUCCESS(rcNt))
     857                            hFile = INVALID_HANDLE_VALUE;
     858                        RtlFreeUnicodeString(&UniStrDynamic);
     859                    }
     860                }
     861                else
     862                    SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: RTStrToUtf16Ex #1 failed: %Rrc\n", rc));
     863
     864                /*
     865                 * If not something that gets remapped, do the half normal searching we need.
     866                 */
     867                if (hFile == INVALID_HANDLE_VALUE)
    810868                {
    811                     { g_System32NtPath.UniStr.Buffer,           g_System32NtPath.UniStr.Length / sizeof(WCHAR) },
    812                     { g_SupLibHardenedExeNtPath.UniStr.Buffer,  g_offSupLibHardenedExeNtName - 1 },
    813                     { pCur->pwszAltSearchDir,                   pCur->cwcAltSearchDir },
    814                 };
    815 
    816                 /* Search System32 first, unless it's a 'V*' or 'm*' name, the latter for msvcrt.  */
    817                 if (   pCur->szName[0] == 'v'
    818                     || pCur->szName[0] == 'V'
    819                     || pCur->szName[0] == 'm'
    820                     || pCur->szName[0] == 'M')
    821                 {
    822                     Tmp      = aDirs[0];
    823                     aDirs[0] = aDirs[1];
    824                     aDirs[1] = Tmp;
    825                 }
    826 
    827                 for (uint32_t i = 0; i < RT_ELEMENTS(aDirs); i++)
    828                 {
    829                     if (aDirs[i].pawcDir && aDirs[i].cwcDir && aDirs[i].cwcDir < RT_ELEMENTS(wszPath) / 3 * 2)
     869                    struct
    830870                    {
    831                         memcpy(wszPath, aDirs[i].pawcDir, aDirs[i].cwcDir * sizeof(RTUTF16));
    832                         uint32_t cwc = aDirs[i].cwcDir;
    833                         wszPath[cwc++] = '\\';
    834                         size_t   cwcName  = RT_ELEMENTS(wszPath) - cwc;
    835                         PRTUTF16 pwszName = &wszPath[cwc];
    836                         int rc = RTStrToUtf16Ex(pCur->szName, RTSTR_MAX, &pwszName, cwcName, &cwcName);
    837                         if (RT_SUCCESS(rc))
     871                        PRTUTF16 pawcDir;
     872                        uint32_t cwcDir;
     873                    } Tmp, aDirs[] =
     874                    {
     875                        { g_System32NtPath.UniStr.Buffer,           g_System32NtPath.UniStr.Length / sizeof(WCHAR) },
     876                        { g_SupLibHardenedExeNtPath.UniStr.Buffer,  g_offSupLibHardenedExeNtName - 1 },
     877                        { pCur->pwszAltSearchDir,                   pCur->cwcAltSearchDir },
     878                    };
     879
     880                    /* Search System32 first, unless it's a 'V*' or 'm*' name, the latter for msvcrt.  */
     881                    if (   pCur->szName[0] == 'v'
     882                        || pCur->szName[0] == 'V'
     883                        || pCur->szName[0] == 'm'
     884                        || pCur->szName[0] == 'M')
     885                    {
     886                        Tmp      = aDirs[0];
     887                        aDirs[0] = aDirs[1];
     888                        aDirs[1] = Tmp;
     889                    }
     890
     891                    for (uint32_t i = 0; i < RT_ELEMENTS(aDirs); i++)
     892                    {
     893                        if (aDirs[i].pawcDir && aDirs[i].cwcDir && aDirs[i].cwcDir < RT_ELEMENTS(wszPath) / 3 * 2)
    838894                        {
    839                             IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
    840                             UNICODE_STRING      NtName;
    841                             NtName.Buffer        = wszPath;
    842                             NtName.Length        = (USHORT)((cwc + cwcName) * sizeof(WCHAR));
    843                             NtName.MaximumLength = NtName.Length + sizeof(WCHAR);
    844                             OBJECT_ATTRIBUTES   ObjAttr;
    845                             InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
    846 
    847                             rcNt = NtCreateFile(&hFile,
    848                                                 FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
    849                                                 &ObjAttr,
    850                                                 &Ios,
    851                                                 NULL /* Allocation Size*/,
    852                                                 FILE_ATTRIBUTE_NORMAL,
    853                                                 FILE_SHARE_READ,
    854                                                 FILE_OPEN,
    855                                                 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
    856                                                 NULL /*EaBuffer*/,
    857                                                 0 /*EaLength*/);
    858                             if (NT_SUCCESS(rcNt))
    859                                 rcNt = Ios.Status;
    860                             if (NT_SUCCESS(rcNt))
    861                                 break;
    862                             hFile = INVALID_HANDLE_VALUE;
     895                            memcpy(wszPath, aDirs[i].pawcDir, aDirs[i].cwcDir * sizeof(RTUTF16));
     896                            uint32_t cwc = aDirs[i].cwcDir;
     897                            wszPath[cwc++] = '\\';
     898                            cwcName  = RT_ELEMENTS(wszPath) - cwc;
     899                            pwszName = &wszPath[cwc];
     900                            rc = RTStrToUtf16Ex(pCur->szName, RTSTR_MAX, &pwszName, cwcName, &cwcName);
     901                            if (RT_SUCCESS(rc))
     902                            {
     903                                IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     904                                UNICODE_STRING      NtName;
     905                                NtName.Buffer        = wszPath;
     906                                NtName.Length        = (USHORT)((cwc + cwcName) * sizeof(WCHAR));
     907                                NtName.MaximumLength = NtName.Length + sizeof(WCHAR);
     908                                OBJECT_ATTRIBUTES   ObjAttr;
     909                                InitializeObjectAttributes(&ObjAttr, &NtName, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
     910
     911                                rcNt = NtCreateFile(&hFile,
     912                                                    FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
     913                                                    &ObjAttr,
     914                                                    &Ios,
     915                                                    NULL /* Allocation Size*/,
     916                                                    FILE_ATTRIBUTE_NORMAL,
     917                                                    FILE_SHARE_READ,
     918                                                    FILE_OPEN,
     919                                                    FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
     920                                                    NULL /*EaBuffer*/,
     921                                                    0 /*EaLength*/);
     922                                if (NT_SUCCESS(rcNt))
     923                                    rcNt = Ios.Status;
     924                                if (NT_SUCCESS(rcNt))
     925                                    break;
     926                                hFile = INVALID_HANDLE_VALUE;
     927                            }
     928                            else
     929                                SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: RTStrToUtf16Ex #2 failed: %Rrc\n", rc));
    863930                        }
    864                         else
    865                             SUP_DPRINTF(("supR3HardenedWinVerifyCacheProcessImportTodos: RTStrToUtf16Ex failed: %Rrc\n", rc));
    866931                    }
    867932                }
     
    15151580supR3HardenedMonitor_LdrLoadDll(PWSTR pwszSearchPath, PULONG pfFlags, PUNICODE_STRING pName, PHANDLE phMod)
    15161581{
    1517     DWORD dwSavedLastError = GetLastError();
     1582    DWORD    dwSavedLastError = GetLastError();
     1583    NTSTATUS rcNt;
    15181584
    15191585    /*
     
    15311597        return STATUS_INVALID_PARAMETER;
    15321598    }
    1533     SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: pName=%.*ls *pfFlags=%#x pwszSearchPath=%ls\n",
    1534                  (unsigned)pName->Length / sizeof(WCHAR), pName->Buffer, pfFlags ? *pfFlags : UINT32_MAX, pwszSearchPath));
     1599    SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: pName=%.*ls *pfFlags=%#x pwszSearchPath=%p:%ls\n",
     1600                 (unsigned)pName->Length / sizeof(WCHAR), pName->Buffer, pfFlags ? *pfFlags : UINT32_MAX, pwszSearchPath,
     1601                 !((uintptr_t)pwszSearchPath & 1) && (uintptr_t)pwszSearchPath >= 0x2000U ? pwszSearchPath : L"<flags>"));
    15351602
    15361603    /*
     
    15621629    }
    15631630    /*
    1564      * Not an absolute path.  Check if it's one of those special API set DLLs.
     1631     * Not an absolute path.  Check if it's one of those special API set DLLs
     1632     * or something we're known to use but should be taken from WinSxS.
    15651633     */
    15661634    else if (supHardViUtf16PathStartsWithEx(pName->Buffer, pName->Length / sizeof(WCHAR),
     
    15751643     * now, either there is no path at all or there is a relative path.  We
    15761644     * will resolve it to an absolute path in either case, failing the call
    1577      * if we can't. If there isn't a path.
     1645     * if we can't.
    15781646     */
    15791647    else
     
    16141682
    16151683        /*
    1616          * Search for the DLL.  Only System32 is allowed as the target of
    1617          * a search on the API level, all VBox calls will have full paths.
     1684         * Perform dll redirection to WinSxS such.  We using an undocumented
     1685         * API here, which as always is a bit risky...  ASSUMES that the API
     1686         * returns a full DOS path.
    16181687         */
    1619         UINT cwc = GetSystemDirectoryW(wszPath, RT_ELEMENTS(wszPath) - 32);
    1620         if (!cwc)
    1621         {
    1622             supR3HardenedError(VINF_SUCCESS, false,
    1623                                "supR3HardenedMonitor_LdrLoadDll: GetSystemDirectoryW failed: %u\n", GetLastError());
    1624             SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_UNEXPECTED_IO_ERROR));
    1625             return STATUS_UNEXPECTED_IO_ERROR;
     1688        UINT            cwc;
     1689        static UNICODE_STRING const s_DefaultSuffix = RTNT_CONSTANT_UNISTR(L".dll");
     1690        UNICODE_STRING  UniStrStatic   = { 0, (USHORT)sizeof(wszPath) - sizeof(WCHAR), wszPath };
     1691        UNICODE_STRING  UniStrDynamic = { 0, 0, NULL };
     1692        PUNICODE_STRING pUniStrResult  = NULL;
     1693        rcNt = RtlDosApplyFileIsolationRedirection_Ustr(1 /*fFlags*/,
     1694                                                        pName,
     1695                                                        (PUNICODE_STRING)&s_DefaultSuffix,
     1696                                                        &UniStrStatic,
     1697                                                        &UniStrDynamic,
     1698                                                        &pUniStrResult,
     1699                                                        NULL /*pNewFlags*/,
     1700                                                        NULL /*pcbFilename*/,
     1701                                                        NULL /*pcbNeeded*/);
     1702        if (NT_SUCCESS(rcNt))
     1703        {
     1704            cwc = pUniStrResult->Length / sizeof(WCHAR);
     1705            if (pUniStrResult != &UniStrDynamic)
     1706                wszPath[cwc] = '\0';
     1707            else
     1708            {
     1709                if (pUniStrResult->Length > sizeof(wszPath) - sizeof(WCHAR))
     1710                {
     1711                    supR3HardenedError(VINF_SUCCESS, false,
     1712                                       "supR3HardenedMonitor_LdrLoadDll: Name too long: %.*ls -> %.*ls (RtlDosApplyFileIoslationRedirection_Ustr)\n",
     1713                                       pName->Length / sizeof(WCHAR), pName->Buffer,
     1714                                       pUniStrResult->Length / sizeof(WCHAR), pUniStrResult->Buffer);
     1715                    RtlFreeUnicodeString(&UniStrDynamic);
     1716                    SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_NAME_TOO_LONG));
     1717                    return STATUS_NAME_TOO_LONG;
     1718                }
     1719                memcpy(&wszPath[0], pUniStrResult->Buffer, pUniStrResult->Length);
     1720                wszPath[cwc] = '\0';
     1721            }
     1722            RtlFreeUnicodeString(&UniStrDynamic);
    16261723        }
    1627         if (cwc + 1 + cwcName + fNeedDllSuffix * 4 >= RT_ELEMENTS(wszPath))
    1628         {
    1629             supR3HardenedError(VINF_SUCCESS, false,
    1630                                "supR3HardenedMonitor_LdrLoadDll: Name too long (system32): %.*ls\n", cwcName, pawcName);
    1631             SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_NAME_TOO_LONG));
    1632             return STATUS_NAME_TOO_LONG;
    1633         }
    1634         wszPath[cwc++] = '\\';
    1635         memcpy(&wszPath[cwc], pawcName, cwcName * sizeof(WCHAR));
    1636         cwc += cwcName;
    1637         if (!fNeedDllSuffix)
    1638             wszPath[cwc] = '\0';
    16391724        else
    16401725        {
    1641             memcpy(&wszPath[cwc], L".dll", 5 * sizeof(WCHAR));
    1642             cwc += 4;
     1726            /*
     1727             * Search for the DLL.  Only System32 is allowed as the target of
     1728             * a search on the API level, all VBox calls will have full paths.
     1729             */
     1730            cwc = GetSystemDirectoryW(wszPath, RT_ELEMENTS(wszPath) - 32);
     1731            if (!cwc)
     1732            {
     1733                supR3HardenedError(VINF_SUCCESS, false,
     1734                                   "supR3HardenedMonitor_LdrLoadDll: GetSystemDirectoryW failed: %u\n", GetLastError());
     1735                SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_UNEXPECTED_IO_ERROR));
     1736                return STATUS_UNEXPECTED_IO_ERROR;
     1737            }
     1738            if (cwc + 1 + cwcName + fNeedDllSuffix * 4 >= RT_ELEMENTS(wszPath))
     1739            {
     1740                supR3HardenedError(VINF_SUCCESS, false,
     1741                                   "supR3HardenedMonitor_LdrLoadDll: Name too long (system32): %.*ls\n", cwcName, pawcName);
     1742                SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: returns rcNt=%#x\n", STATUS_NAME_TOO_LONG));
     1743                return STATUS_NAME_TOO_LONG;
     1744            }
     1745            wszPath[cwc++] = '\\';
     1746            memcpy(&wszPath[cwc], pawcName, cwcName * sizeof(WCHAR));
     1747            cwc += cwcName;
     1748            if (!fNeedDllSuffix)
     1749                wszPath[cwc] = '\0';
     1750            else
     1751            {
     1752                memcpy(&wszPath[cwc], L".dll", 5 * sizeof(WCHAR));
     1753                cwc += 4;
     1754            }
    16431755        }
    16441756
     
    16471759        ResolvedName.MaximumLength = ResolvedName.Length + sizeof(WCHAR);
    16481760
    1649         SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: '%.*ls' -> '%.*ls'\n",
     1761        SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: '%.*ls' -> '%.*ls' [rcNt=%#x]\n",
    16501762                     (unsigned)pName->Length / sizeof(WCHAR), pName->Buffer,
    1651                      ResolvedName.Length / sizeof(WCHAR), ResolvedName.Buffer));
     1763                     ResolvedName.Length / sizeof(WCHAR), ResolvedName.Buffer, rcNt));
    16521764        pName = &ResolvedName;
    16531765    }
    16541766
    1655     NTSTATUS rcNt;
    16561767    if (!fSkipValidation)
    16571768    {
  • trunk/src/VBox/HostDrivers/Support/win/import-template-ntdll.h

    r52365 r52627  
    6060SUPHARNT_IMPORT_STDCALL(RtlCreateUserThread, 40)
    6161SUPHARNT_IMPORT_STDCALL(RtlDestroyProcessParameters, 4)
     62SUPHARNT_IMPORT_STDCALL(RtlDosApplyFileIsolationRedirection_Ustr, 36)
    6263SUPHARNT_IMPORT_STDCALL(RtlEqualSid, 8)
    6364SUPHARNT_IMPORT_STDCALL(RtlExpandEnvironmentStrings_U, 16)
     65SUPHARNT_IMPORT_STDCALL(RtlFreeUnicodeString, 4)
    6466SUPHARNT_IMPORT_STDCALL(RtlGetVersion, 4)
    6567SUPHARNT_IMPORT_STDCALL(RtlInitializeSid, 12)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette