VirtualBox

Ignore:
Timestamp:
Jul 1, 2015 2:01:43 PM (9 years ago)
Author:
vboxsync
Message:

SUPHardNt: Allow hardened exectuable binaries in the 'testcase' subdirectory.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r56293 r56733  
    3535#endif
    3636#ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR
    37 # define LOAD_LIBRARY_SEARCH_APPLICATION_DIR    0x200
    38 # define LOAD_LIBRARY_SEARCH_SYSTEM32           0x800
     37# define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR       UINT32_C(0x100)
     38# define LOAD_LIBRARY_SEARCH_APPLICATION_DIR    UINT32_C(0x200)
     39# define LOAD_LIBRARY_SEARCH_USER_DIRS          UINT32_C(0x400)
     40# define LOAD_LIBRARY_SEARCH_SYSTEM32           UINT32_C(0x800)
    3941#endif
    4042
     
    274276/** The NT path of the executable. */
    275277SUPSYSROOTDIRBUF            g_SupLibHardenedExeNtPath;
     278/** The NT path of the application binary directory. */
     279SUPSYSROOTDIRBUF            g_SupLibHardenedAppBinNtPath;
    276280/** The offset into g_SupLibHardenedExeNtPath of the executable name (WCHAR,
    277281 * not byte). This also gives the length of the exectuable directory path,
    278282 * including a trailing slash. */
    279 uint32_t                    g_offSupLibHardenedExeNtName;
     283static uint32_t             g_offSupLibHardenedExeNtName;
     284/** Set if we need to use the LOAD_LIBRARY_SEARCH_USER_DIRS option. */
     285bool                        g_fSupLibHardenedDllSearchUserDirs = false;
    280286/** @} */
    281287
     
    464470        if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0))
    465471        {
    466            fFlags |= LOAD_LIBRARY_SEARCH_SYSTEM32;
    467            if (!fSystem32Only)
    468                fFlags |= LOAD_LIBRARY_SEARCH_APPLICATION_DIR;
     472            fFlags |= LOAD_LIBRARY_SEARCH_SYSTEM32;
     473            if (!fSystem32Only)
     474            {
     475                fFlags |= LOAD_LIBRARY_SEARCH_APPLICATION_DIR;
     476                if (g_fSupLibHardenedDllSearchUserDirs)
     477                    fFlags |= LOAD_LIBRARY_SEARCH_USER_DIRS;
     478            }
    469479        }
    470480
     
    806816                        continue;
    807817                    }
    808                     if (supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardenedExeNtPath.UniStr.Buffer,
    809                                                                 g_offSupLibHardenedExeNtName,
     818                    if (supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardenedAppBinNtPath.UniStr.Buffer,
     819                                                                g_SupLibHardenedAppBinNtPath.UniStr.Length / sizeof(CHAR),
    810820                                                                uBuf.szName) != NULL)
    811821                    {
     
    889899                                                            g_System32NtPath.UniStr.Length / sizeof(WCHAR),
    890900                                                            pCur->szName)
    891                 && !supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardenedExeNtPath.UniStr.Buffer,
    892                                                             g_offSupLibHardenedExeNtName,
     901                && !supR3HardenedWinVerifyCacheLookupImport(g_SupLibHardenedAppBinNtPath.UniStr.Buffer,
     902                                                            g_SupLibHardenedAppBinNtPath.UniStr.Length / sizeof(WCHAR),
    893903                                                            pCur->szName)
    894904                && (   pCur->cwcAltSearchDir == 0
     
    983993                    {
    984994                        { g_System32NtPath.UniStr.Buffer,           g_System32NtPath.UniStr.Length / sizeof(WCHAR) },
    985                         { g_SupLibHardenedExeNtPath.UniStr.Buffer,  g_offSupLibHardenedExeNtName - 1 },
     995                        { g_SupLibHardenedExeNtPath.UniStr.Buffer,  g_SupLibHardenedAppBinNtPath.UniStr.Length / sizeof(WCHAR) },
    986996                        { pCur->pwszAltSearchDir,                   pCur->cwcAltSearchDir },
    987997                    };
     
    13521362     *      7. x86 variations of 4 & 5 - ditto.
    13531363     */
    1354     Assert(g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] == '\\');
    13551364    uint32_t fFlags = 0;
    13561365    if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_System32NtPath.UniStr, true /*fCheckSlash*/))
     
    13581367    else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_WinSxSNtPath.UniStr, true /*fCheckSlash*/))
    13591368        fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
    1360     else if (supHardViUtf16PathStartsWithEx(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR),
    1361                                             g_SupLibHardenedExeNtPath.UniStr.Buffer,
    1362                                             g_offSupLibHardenedExeNtName, false /*fCheckSlash*/))
     1369    else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_SupLibHardenedAppBinNtPath.UniStr, true /*fCheckSlash*/))
    13631370        fFlags |= SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING | SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT;
    13641371# ifdef VBOX_PERMIT_MORE
     
    14041411     * integrity checks.
    14051412     */
    1406     Assert(g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] == '\\');
    14071413    uint32_t fFlags = 0;
    1408     if (supHardViUtf16PathStartsWithEx(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR),
    1409                                        g_SupLibHardenedExeNtPath.UniStr.Buffer,
    1410                                        g_offSupLibHardenedExeNtName, false /*fCheckSlash*/))
     1414    if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_SupLibHardenedAppBinNtPath.UniStr, true /*fCheckSlash*/))
    14111415        fFlags |= SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING | SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT;
    14121416    else
     
    46494653                              "Window Vista without any service pack installed is not supported. Please install the latest service pack.");
    46504654#endif
     4655}
     4656
     4657
     4658/**
     4659 * Modifies the DLL search path for testcases.
     4660 *
     4661 * This makes sure the application binary path is in the search path.  When
     4662 * starting a testcase executable in the testcase/ subdirectory this isn't the
     4663 * case by default.  So, unless we do something about it we won't be able to
     4664 * import VBox DLLs.
     4665 *
     4666 * @param   fFlags          The main flags (giving the location).
     4667 * @param   pszAppBinPath   The path to the application binary directory
     4668 *                          (windows style).
     4669 */
     4670DECLHIDDEN(void) supR3HardenedWinModifyDllSearchPath(uint32_t fFlags, const char *pszAppBinPath)
     4671{
     4672    /*
     4673     * For the testcases to work, we must add the app bin directory to the
     4674     * DLL search list before the testcase dll is loaded or it won't be
     4675     * able to find the VBox DLLs.  This is done _after_ VBoxRT.dll is
     4676     * initialized and sets its defaults.
     4677     */
     4678    switch (fFlags & SUPSECMAIN_FLAGS_LOC_MASK)
     4679    {
     4680        case SUPSECMAIN_FLAGS_LOC_TESTCASE:
     4681            break;
     4682        default:
     4683            return;
     4684    }
     4685
     4686    /*
     4687     * Dynamically resolve the two APIs we need (the latter uses forwarders on w7).
     4688     */
     4689    HMODULE hModKernel32 = GetModuleHandleW(L"kernel32.dll");
     4690
     4691    typedef BOOL (WINAPI *PFNSETDLLDIRECTORY)(LPCWSTR);
     4692    PFNSETDLLDIRECTORY pfnSetDllDir;
     4693    pfnSetDllDir     = (PFNSETDLLDIRECTORY)GetProcAddress(hModKernel32, "SetDllDirectoryW");
     4694
     4695    typedef BOOL (WINAPI *PFNSETDEFAULTDLLDIRECTORIES)(DWORD);
     4696    PFNSETDEFAULTDLLDIRECTORIES pfnSetDefDllDirs;
     4697    pfnSetDefDllDirs = (PFNSETDEFAULTDLLDIRECTORIES)GetProcAddress(hModKernel32, "SetDefaultDllDirectories");
     4698
     4699    if (pfnSetDllDir != NULL)
     4700    {
     4701        /*
     4702         * Convert the path to UTF-16 and try set it.
     4703         */
     4704        PRTUTF16 pwszAppBinPath = NULL;
     4705        int rc = RTStrToUtf16(pszAppBinPath, &pwszAppBinPath);
     4706        if (RT_SUCCESS(rc))
     4707        {
     4708            if (pfnSetDllDir(pwszAppBinPath))
     4709            {
     4710                SUP_DPRINTF(("supR3HardenedWinModifyDllSearchPath: Set dll dir to '%ls'\n", pwszAppBinPath));
     4711                g_fSupLibHardenedDllSearchUserDirs = true;
     4712
     4713                /*
     4714                 * We set it alright, on W7 and later we also must modify the
     4715                 * default DLL search order.  See @bugref{6861} for details on
     4716                 * why we don't do this on Vista (also see init-win.cpp in IPRT).
     4717                 */
     4718                if (   pfnSetDefDllDirs
     4719                    && g_uNtVerCombined >= SUP_NT_VER_W70)
     4720                {
     4721                    if (pfnSetDefDllDirs(  LOAD_LIBRARY_SEARCH_APPLICATION_DIR
     4722                                         | LOAD_LIBRARY_SEARCH_SYSTEM32
     4723                                         | LOAD_LIBRARY_SEARCH_USER_DIRS))
     4724                        SUP_DPRINTF(("supR3HardenedWinModifyDllSearchPath: Successfully modified search dirs.\n"));
     4725                    else
     4726                        supR3HardenedFatal("supR3HardenedWinModifyDllSearchPath: SetDllDirectoryW(%ls) failed: %d\n",
     4727                                           pwszAppBinPath, RtlGetLastWin32Error());
     4728                }
     4729            }
     4730            else
     4731                supR3HardenedFatal("supR3HardenedWinModifyDllSearchPath: SetDllDirectoryW(%ls) failed: %d\n",
     4732                                   pwszAppBinPath, RtlGetLastWin32Error());
     4733            RTUtf16Free(pwszAppBinPath);
     4734        }
     4735        else
     4736            supR3HardenedFatal("supR3HardenedWinModifyDllSearchPath: RTStrToUtf16(%s) failed: %d\n", pszAppBinPath, rc);
     4737    }
     4738}
     4739
     4740
     4741/**
     4742 * Initializes the application binary directory path.
     4743 *
     4744 * This is called once or twice.
     4745 *
     4746 * @param   fFlags          The main flags (giving the location).
     4747 */
     4748DECLHIDDEN(void) supR3HardenedWinInitAppBin(uint32_t fFlags)
     4749{
     4750    USHORT cwc = (USHORT)g_offSupLibHardenedExeNtName - 1;
     4751    g_SupLibHardenedAppBinNtPath.UniStr.Buffer = g_SupLibHardenedAppBinNtPath.awcBuffer;
     4752    memcpy(g_SupLibHardenedAppBinNtPath.UniStr.Buffer, g_SupLibHardenedExeNtPath.UniStr.Buffer, cwc * sizeof(WCHAR));
     4753
     4754    switch (fFlags & SUPSECMAIN_FLAGS_LOC_MASK)
     4755    {
     4756        case SUPSECMAIN_FLAGS_LOC_APP_BIN:
     4757            break;
     4758        case SUPSECMAIN_FLAGS_LOC_TESTCASE:
     4759        {
     4760            /* Drop one directory level. */
     4761            USHORT off = cwc;
     4762            WCHAR  wc;
     4763            while (   off > 1
     4764                   && (wc = g_SupLibHardenedAppBinNtPath.UniStr.Buffer[off - 1]) != '\0')
     4765                if (wc != '\\' && wc != '/')
     4766                    off--;
     4767                else
     4768                {
     4769                    if (g_SupLibHardenedAppBinNtPath.UniStr.Buffer[off - 2] == ':')
     4770                        cwc = off;
     4771                    else
     4772                        cwc = off - 1;
     4773                    break;
     4774                }
     4775            break;
     4776        }
     4777        default:
     4778            supR3HardenedFatal("supR3HardenedWinInitAppBin: Unknown program binary location: %#x\n", fFlags);
     4779    }
     4780
     4781    g_SupLibHardenedAppBinNtPath.UniStr.Buffer[cwc]   = '\0';
     4782    g_SupLibHardenedAppBinNtPath.UniStr.Length        = cwc * sizeof(WCHAR);
     4783    g_SupLibHardenedAppBinNtPath.UniStr.MaximumLength = sizeof(g_SupLibHardenedAppBinNtPath.awcBuffer);
     4784    SUP_DPRINTF(("supR3HardenedWinInitAppBin(%#x): '%ls'\n", fFlags, g_SupLibHardenedAppBinNtPath.UniStr.Buffer));
    46514785}
    46524786
     
    53725506
    53735507    /*
     5508     * Preliminary app binary path init.  May change when SUPR3HardenedMain is
     5509     * called (via main below).
     5510     */
     5511    supR3HardenedWinInitAppBin(SUPSECMAIN_FLAGS_LOC_APP_BIN);
     5512
     5513    /*
    53745514     * If we've done early init already, register the DLL load notification
    53755515     * callback and reinstall the NtDll patches.
     
    55665706
    55675707    /*
     5708     * Preliminary app binary path init.  May change when SUPR3HardenedMain is called.
     5709     */
     5710    supR3HardenedWinInitAppBin(SUPSECMAIN_FLAGS_LOC_APP_BIN);
     5711
     5712    /*
    55685713     * Initialize the image verification stuff (hooks LdrLoadDll and NtCreateSection).
    55695714     */
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