VirtualBox

Changeset 2961 in kBuild


Ignore:
Timestamp:
Sep 22, 2016 7:41:00 PM (8 years ago)
Author:
bird
Message:

kWorker: Better handling of fixed allocations in cl.exe, avoiding that fatal /Ym error with precompiled headers.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/kWorker.c

    r2959 r2961  
    9696 * Keep history of the last jobs.  For debugging.  */
    9797#define WITH_HISTORY
     98
     99/** @def WITH_FIXED_VIRTUAL_ALLOCS
     100 * Whether to pre allocate memory for known fixed VirtualAlloc calls (currently
     101 * there is only one, but an important one, from cl.exe).
     102 */
     103#if K_ARCH == K_ARCH_X86_32
     104# define WITH_FIXED_VIRTUAL_ALLOCS
     105#endif
    98106
    99107/** @def WITH_PCH_CACHING
     
    338346    /** Cached file handle. */
    339347    HANDLE              hCached;
     348    /** Cached file section handle. */
     349    HANDLE              hSection;
    340350    /** Cached file content. */
    341351    KU8                *pbCached;
     
    572582    void               *pvAlloc;
    573583    KSIZE               cbAlloc;
     584    /** This is KU32_MAX if not a preallocated chunk. */
     585    KU32                idxPreAllocated;
    574586} KWVIRTALLOC;
    575587
     
    896908static KBOOL        g_fRestart = K_FALSE;
    897909
     910/** Whether control-C/SIGINT or Control-Break/SIGBREAK have been seen. */
     911static KBOOL volatile g_fCtrlC = K_FALSE;
     912
    898913/* Further down. */
    899914extern KWREPLACEMENTFUNCTION const g_aSandboxReplacements[];
     
    919934/** Log file handle.   */
    920935static HANDLE g_hLogFile = INVALID_HANDLE_VALUE;
     936#endif
     937
     938
     939#ifdef WITH_FIXED_VIRTUAL_ALLOCS
     940/** Virtual address space reserved for CL.EXE heap manager.
     941 *
     942 * Visual C++ 2010 reserves a 78MB chunk of memory from cl.exe at a fixed
     943 * address.  It's among other things used for precompiled headers, which
     944 * seemingly have addresses hardcoded into them and won't work if mapped
     945 * elsewhere.  Thus, we have to make sure the area is available when cl.exe asks
     946 * for it.  (The /Zm option may affect this allocation.)
     947 */
     948static struct
     949{
     950    /** The memory address we need.   */
     951    KUPTR const     uFixed;
     952    /** How much we need to fix. */
     953    KSIZE const     cbFixed;
     954    /** What we actually got, NULL if given back. */
     955    void           *pvReserved;
     956    /** Whether it is in use or not. */
     957    KBOOL           fInUse;
     958} g_aFixedVirtualAllocs[] =
     959{
     960# if K_ARCH == K_ARCH_X86_32
     961    /* Visual C++ 2010 reserves 0x04b00000, Visual C++ 2015 reserves 0x05300000. We get 0x06800000. */
     962    { KUPTR_C(        0x11000000), KSIZE_C(        0x06800000), NULL },
     963# else
     964    { KUPTR_C(0x000006BB00000000), KSIZE_C(0x000000002EE00000), NULL },
     965# endif
     966};
    921967#endif
    922968
     
    44744520
    44754521
     4522#ifndef NDEBUG
     4523/*
     4524 * This wraps up to three InvokeCompilerPassW functions and dumps their arguments to the log.
     4525 */
     4526# if K_ARCH == K_ARCH_X86_32
     4527static char g_szInvokeCompilePassW[] = "_InvokeCompilerPassW@16";
     4528# else
     4529static char g_szInvokeCompilePassW[] = "InvokeCompilerPassW";
     4530# endif
     4531typedef KIPTR __stdcall FNINVOKECOMPILERPASSW(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance);
     4532typedef FNINVOKECOMPILERPASSW *PFNINVOKECOMPILERPASSW;
     4533typedef struct KWCXINTERCEPTORENTRY
     4534{
     4535    PFNINVOKECOMPILERPASSW  pfnOrg;
     4536    PKWMODULE               pModule;
     4537    PFNINVOKECOMPILERPASSW  pfnWrap;
     4538} KWCXINTERCEPTORENTRY;
     4539
     4540static KIPTR kwSandbox_Cx_InvokeCompilerPassW_Common(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance,
     4541                                                     KWCXINTERCEPTORENTRY *pEntry)
     4542{
     4543    int i;
     4544    KIPTR rcExit;
     4545    KW_LOG(("%s!InvokeCompilerPassW(%d, %p, %#x, %p)\n",
     4546            &pEntry->pModule->pszPath[pEntry->pModule->offFilename], cArgs, papwszArgs, fFlags, phCluiInstance));
     4547    for (i = 0; i < cArgs; i++)
     4548        KW_LOG((" papwszArgs[%u]='%ls'\n", i, papwszArgs[i]));
     4549
     4550    rcExit = pEntry->pfnOrg(cArgs, papwszArgs, fFlags, phCluiInstance);
     4551
     4552    KW_LOG(("%s!InvokeCompilerPassW returns %d\n", &pEntry->pModule->pszPath[pEntry->pModule->offFilename], rcExit));
     4553    return rcExit;
     4554}
     4555
     4556static FNINVOKECOMPILERPASSW kwSandbox_Cx_InvokeCompilerPassW_0;
     4557static FNINVOKECOMPILERPASSW kwSandbox_Cx_InvokeCompilerPassW_1;
     4558static FNINVOKECOMPILERPASSW kwSandbox_Cx_InvokeCompilerPassW_2;
     4559
     4560static KWCXINTERCEPTORENTRY g_aCxInterceptorEntries[] =
     4561{
     4562    { NULL, NULL, kwSandbox_Cx_InvokeCompilerPassW_0 },
     4563    { NULL, NULL, kwSandbox_Cx_InvokeCompilerPassW_1 },
     4564    { NULL, NULL, kwSandbox_Cx_InvokeCompilerPassW_2 },
     4565};
     4566
     4567static KIPTR __stdcall kwSandbox_Cx_InvokeCompilerPassW_0(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance)
     4568{
     4569    return kwSandbox_Cx_InvokeCompilerPassW_Common(cArgs, papwszArgs, fFlags, phCluiInstance, &g_aCxInterceptorEntries[0]);
     4570}
     4571
     4572static KIPTR __stdcall kwSandbox_Cx_InvokeCompilerPassW_1(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance)
     4573{
     4574    return kwSandbox_Cx_InvokeCompilerPassW_Common(cArgs, papwszArgs, fFlags, phCluiInstance, &g_aCxInterceptorEntries[1]);
     4575}
     4576
     4577static KIPTR __stdcall kwSandbox_Cx_InvokeCompilerPassW_2(int cArgs, wchar_t **papwszArgs, KUPTR fFlags, void **phCluiInstance)
     4578{
     4579    return kwSandbox_Cx_InvokeCompilerPassW_Common(cArgs, papwszArgs, fFlags, phCluiInstance, &g_aCxInterceptorEntries[2]);
     4580}
     4581
     4582#endif /* !NDEBUG */
     4583
     4584
    44764585/** Kernel32 - GetProcAddress()   */
    44774586static FARPROC WINAPI kwSandbox_Kernel32_GetProcAddress(HMODULE hmod, LPCSTR pszProc)
     
    45224631                }
    45234632
     4633#ifndef NDEBUG
     4634            /* Intercept the compiler pass method, dumping arguments. */
     4635            if (kHlpStrComp(pszProc, g_szInvokeCompilePassW) == 0)
     4636            {
     4637                KU32 i;
     4638                for (i = 0; i < K_ELEMENTS(g_aCxInterceptorEntries); i++)
     4639                    if ((KUPTR)g_aCxInterceptorEntries[i].pfnOrg == uValue)
     4640                    {
     4641                        uValue = (KUPTR)g_aCxInterceptorEntries[i].pfnWrap;
     4642                        KW_LOG(("GetProcAddress: intercepting InvokeCompilerPassW\n"));
     4643                        break;
     4644                    }
     4645                if (i >= K_ELEMENTS(g_aCxInterceptorEntries))
     4646                    while (i-- > 0)
     4647                        if (g_aCxInterceptorEntries[i].pfnOrg == NULL)
     4648                        {
     4649                            g_aCxInterceptorEntries[i].pfnOrg  = (PFNINVOKECOMPILERPASSW)(KUPTR)uValue;
     4650                            g_aCxInterceptorEntries[i].pModule = pMod;
     4651                            uValue = (KUPTR)g_aCxInterceptorEntries[i].pfnWrap;
     4652                            KW_LOG(("GetProcAddress: intercepting InvokeCompilerPassW (new)\n"));
     4653                            break;
     4654                        }
     4655            }
     4656#endif
    45244657            KW_LOG(("GetProcAddress(%s, %s) -> %p\n", pMod->pszPath, pszProc, (KUPTR)uValue));
    45254658            kwLdrModuleRelease(pMod);
     
    51255258            {
    51265259                KU32 cbCache = (KU32)cbFile.QuadPart;
    5127 #if 0
    5128                 KU8 *pbCache = (KU8 *)kHlpAlloc(cbCache);
    5129                 if (pbCache)
    5130                 {
    5131                     DWORD cbActually = 0;
    5132                     if (   ReadFile(hFile, pbCache, cbCache, &cbActually, NULL)
    5133                         && cbActually == cbCache)
    5134                     {
    5135                         LARGE_INTEGER offZero;
    5136                         offZero.QuadPart = 0;
    5137                         if (SetFilePointerEx(hFile, offZero, NULL /*poffNew*/, FILE_BEGIN))
    5138                         {
    5139 #else
    51405260                HANDLE hMapping = CreateFileMappingW(hFile, NULL /*pSecAttrs*/,  PAGE_READONLY,
    51415261                                                     0 /*cbMaxLow*/, 0 /*cbMaxHigh*/, NULL /*pwszName*/);
     
    51435263                {
    51445264                    KU8 *pbCache = (KU8 *)MapViewOfFile(hMapping, FILE_MAP_READ, 0 /*offFileHigh*/, 0 /*offFileLow*/, cbCache);
    5145                     CloseHandle(hMapping);
    51465265                    if (pbCache)
    51475266                    {
    5148 #endif
    5149                             /*
    5150                              * Create the cached file object.
    5151                              */
    5152                             PKFSWCACHEDFILE pCachedFile;
    5153                             KU32            cbPath = pFsObj->cchParent + pFsObj->cchName + 2;
    5154                             pCachedFile = (PKFSWCACHEDFILE)kFsCacheObjAddUserData(g_pFsCache, pFsObj, KW_DATA_KEY_CACHED_FILE,
    5155                                                                                   sizeof(*pCachedFile) + cbPath);
    5156                             if (pCachedFile)
    5157                             {
    5158                                 pCachedFile->hCached  = hFile;
    5159                                 pCachedFile->cbCached = cbCache;
    5160                                 pCachedFile->pbCached = pbCache;
    5161                                 pCachedFile->pFsObj   = pFsObj;
    5162                                 kFsCacheObjGetFullPathA(pFsObj, pCachedFile->szPath, cbPath, '/');
    5163                                 kFsCacheObjRetain(pFsObj);
    5164                                 KWFS_LOG(("Cached '%s': %p LB %#x, hCached=%p\n", pCachedFile->szPath, pbCache, cbCache, hFile));
    5165                                 return pCachedFile;
    5166                             }
    5167 
    5168                             KWFS_LOG(("Failed to allocate KFSWCACHEDFILE structure!\n"));
    5169 #if 1
     5267                        /*
     5268                         * Create the cached file object.
     5269                         */
     5270                        PKFSWCACHEDFILE pCachedFile;
     5271                        KU32            cbPath = pFsObj->cchParent + pFsObj->cchName + 2;
     5272                        pCachedFile = (PKFSWCACHEDFILE)kFsCacheObjAddUserData(g_pFsCache, pFsObj, KW_DATA_KEY_CACHED_FILE,
     5273                                                                              sizeof(*pCachedFile) + cbPath);
     5274                        if (pCachedFile)
     5275                        {
     5276                            pCachedFile->hCached  = hFile;
     5277                            pCachedFile->hSection = hMapping;
     5278                            pCachedFile->cbCached = cbCache;
     5279                            pCachedFile->pbCached = pbCache;
     5280                            pCachedFile->pFsObj   = pFsObj;
     5281                            kFsCacheObjGetFullPathA(pFsObj, pCachedFile->szPath, cbPath, '/');
     5282                            kFsCacheObjRetain(pFsObj);
     5283                            KWFS_LOG(("Cached '%s': %p LB %#x, hCached=%p\n", pCachedFile->szPath, pbCache, cbCache, hFile));
     5284                            return pCachedFile;
     5285                        }
     5286
     5287                        KWFS_LOG(("Failed to allocate KFSWCACHEDFILE structure!\n"));
    51705288                    }
    51715289                    else
    51725290                        KWFS_LOG(("Failed to cache file: MapViewOfFile failed: %u\n", GetLastError()));
     5291                    CloseHandle(hMapping);
    51735292                }
    51745293                else
    51755294                    KWFS_LOG(("Failed to cache file: CreateFileMappingW failed: %u\n", GetLastError()));
    5176 #else
    5177                         }
    5178                         else
    5179                             KWFS_LOG(("Failed to seek to start of cached file! err=%u\n", GetLastError()));
    5180                     }
    5181                     else
    5182                         KWFS_LOG(("Failed to read %#x bytes into cache! err=%u cbActually=%#x\n",
    5183                                   cbCache, GetLastError(), cbActually));
    5184                     kHlpFree(pbCache);
    5185                 }
    5186                 else
    5187                     KWFS_LOG(("Failed to allocate %#x bytes for cache!\n", cbCache));
    5188 #endif
    51895295            }
    51905296            else
     
    52085314{
    52095315    HANDLE hProcSelf = GetCurrentProcess();
    5210     if (DuplicateHandle(hProcSelf, pCachedFile->hCached,
     5316    if (DuplicateHandle(hProcSelf, fIsFileHandle ? pCachedFile->hCached : pCachedFile->hSection,
    52115317                        hProcSelf, phFile,
    52125318                        dwDesiredAccess, fInheritHandle,
     
    55265632            if (pcbMoveHi)
    55275633                *pcbMoveHi = (KU64)offMove >> 32;
    5528             KWFS_LOG(("SetFilePointer(%p) -> %#llx [cached]\n", hFile, offMove));
     5634            KWFS_LOG(("SetFilePointer(%p,%#x,?,%u) -> %#llx [%s]\n", hFile, cbMove, dwMoveMethod, offMove,
     5635                      pHandle->enmType == KWHANDLETYPE_FSOBJ_READ_CACHE ? "cached" : "temp"));
    55295636            SetLastError(NO_ERROR);
    55305637            return (KU32)offMove;
     
    56085715            if (poffNew)
    56095716                poffNew->QuadPart = offMyMove;
    5610             KWFS_LOG(("SetFilePointerEx(%p) -> TRUE, %#llx [cached]\n", hFile, offMyMove));
     5717            KWFS_LOG(("SetFilePointerEx(%p,%#llx,,%u) -> TRUE, %#llx [%s]\n", hFile, offMove.QuadPart, dwMoveMethod, offMyMove,
     5718                      pHandle->enmType == KWHANDLETYPE_FSOBJ_READ_CACHE ? "cached" : "temp"));
    56115719            return TRUE;
    56125720        }
     
    59476055{
    59486056    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile);
    5949     kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
     6057    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_fCtrlC);
    59506058    if (idxHandle < g_Sandbox.cHandles)
    59516059    {
     
    64996607    return pvRet;
    65006608}
    6501 /** @todo MapViewOfFileEx */
    6502 
     6609
     6610
     6611/** Kernel32 - MapViewOfFileEx  */
     6612static PVOID WINAPI kwSandbox_Kernel32_MapViewOfFileEx(HANDLE hSection, DWORD dwDesiredAccess,
     6613                                                       DWORD offFileHigh, DWORD offFileLow, SIZE_T cbToMap, PVOID pvMapAddr)
     6614{
     6615    PVOID       pvRet;
     6616    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hSection);
     6617    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
     6618    if (idxHandle < g_Sandbox.cHandles)
     6619    {
     6620        PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle];
     6621        if (pHandle != NULL)
     6622        {
     6623            switch (pHandle->enmType)
     6624            {
     6625                case KWHANDLETYPE_TEMP_FILE_MAPPING:
     6626                    KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) - temporary file!\n",
     6627                              hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr));
     6628                    if (!pvMapAddr)
     6629                        return kwSandbox_Kernel32_MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap);
     6630                    kHlpAssertFailed();
     6631                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     6632                    return NULL;
     6633
     6634                case KWHANDLETYPE_FSOBJ_READ_CACHE_MAPPING:
     6635                    KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) - read cached file!\n",
     6636                              hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr));
     6637                    if (!pvMapAddr)
     6638                        return kwSandbox_Kernel32_MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap);
     6639                    /* We can use fallback here as the handle is an actual section handle. */
     6640                    break;
     6641
     6642                case KWHANDLETYPE_FSOBJ_READ_CACHE:
     6643                case KWHANDLETYPE_TEMP_FILE:
     6644                case KWHANDLETYPE_OUTPUT_BUF:
     6645                default:
     6646                    kHlpAssertFailed();
     6647                    SetLastError(ERROR_INVALID_OPERATION);
     6648                    return NULL;
     6649            }
     6650        }
     6651    }
     6652
     6653    pvRet = MapViewOfFileEx(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr);
     6654    KWFS_LOG(("MapViewOfFileEx(%p, %#x, %#x, %#x, %#x, %p) -> %p\n",
     6655              hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pvMapAddr, pvRet));
     6656    return pvRet;
     6657
     6658}
    65036659
    65046660/** Kernel32 - UnmapViewOfFile  */
     
    66016757    BOOL        fRet;
    66026758    KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hObject);
    6603     kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
     6759    kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread || g_fCtrlC);
    66046760    if (idxHandle < g_Sandbox.cHandles)
    66056761    {
     
    73287484 */
    73297485
    7330 /** Kernel32 - VirtualAlloc - for c1[xx].dll 78GB leaks.   */
     7486#ifdef WITH_FIXED_VIRTUAL_ALLOCS
     7487
     7488/** For debug logging.  */
     7489# ifndef NDEBUG
     7490static void kwSandboxLogFixedAllocation(KU32 idxFixed, const char *pszWhere)
     7491{
     7492    MEMORY_BASIC_INFORMATION MemInfo = { NULL, NULL, 0, 0, 0, 0, 0};
     7493    SIZE_T cbMemInfo = VirtualQuery(g_aFixedVirtualAllocs[idxFixed].pvReserved, &MemInfo, sizeof(MemInfo));
     7494    kHlpAssert(cbMemInfo == sizeof(MemInfo));
     7495    if (cbMemInfo != 0)
     7496        KW_LOG(("%s: #%u %p LB %#x: base=%p alloc=%p region=%#x state=%#x prot=%#x type=%#x\n",
     7497                pszWhere, idxFixed, g_aFixedVirtualAllocs[idxFixed].pvReserved, g_aFixedVirtualAllocs[idxFixed].cbFixed,
     7498                MemInfo.BaseAddress,
     7499                MemInfo.AllocationBase,
     7500                MemInfo.RegionSize,
     7501                MemInfo.State,
     7502                MemInfo.Protect,
     7503                MemInfo.Type));
     7504}
     7505# else
     7506#  define kwSandboxLogFixedAllocation(idxFixed, pszWhere) do { } while (0)
     7507# endif
     7508
     7509/**
     7510 * Used by both kwSandbox_Kernel32_VirtualFree and kwSandboxCleanupLate
     7511 *
     7512 * @param   idxFixed        The fixed allocation index to "free".
     7513 */
     7514static void kwSandboxResetFixedAllocation(KU32 idxFixed)
     7515{
     7516    BOOL fRc;
     7517    kwSandboxLogFixedAllocation(idxFixed, "kwSandboxResetFixedAllocation[pre]");
     7518    fRc = VirtualFree(g_aFixedVirtualAllocs[idxFixed].pvReserved, g_aFixedVirtualAllocs[idxFixed].cbFixed, MEM_DECOMMIT);
     7519    kHlpAssert(fRc); K_NOREF(fRc);
     7520    kwSandboxLogFixedAllocation(idxFixed, "kwSandboxResetFixedAllocation[pst]");
     7521    g_aFixedVirtualAllocs[idxFixed].fInUse = K_FALSE;
     7522}
     7523
     7524#endif /* WITH_FIXED_VIRTUAL_ALLOCS */
     7525
     7526
     7527/** Kernel32 - VirtualAlloc - for managing  cl.exe / c1[xx].dll heap with fixed
     7528 * location (~78MB in 32-bit 2010 compiler). */
    73317529static PVOID WINAPI kwSandbox_Kernel32_VirtualAlloc(PVOID pvAddr, SIZE_T cb, DWORD fAllocType, DWORD fProt)
    73327530{
    7333     PVOID pvMem = VirtualAlloc(pvAddr, cb, fAllocType, fProt);
     7531    PVOID pvMem;
     7532    if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL)
     7533    {
     7534        KU32 idxPreAllocated = KU32_MAX;
     7535
     7536#ifdef WITH_FIXED_VIRTUAL_ALLOCS
     7537        /*
     7538         * Look for a pre-reserved CL.exe heap allocation.
     7539         */
     7540        pvMem = NULL;
     7541        if (   pvAddr != 0
     7542            && (fAllocType & MEM_RESERVE))
     7543        {
     7544            KU32 idxFixed = K_ELEMENTS(g_aFixedVirtualAllocs);
     7545            kHlpAssert(!(fAllocType & ~(MEM_RESERVE | MEM_TOP_DOWN)));
     7546            while (idxFixed-- > 0)
     7547                if (   g_aFixedVirtualAllocs[idxFixed].uFixed == (KUPTR)pvAddr
     7548                    && g_aFixedVirtualAllocs[idxFixed].pvReserved)
     7549                {
     7550                    if (g_aFixedVirtualAllocs[idxFixed].cbFixed >= cb)
     7551                    {
     7552                        if (!g_aFixedVirtualAllocs[idxFixed].fInUse)
     7553                        {
     7554                            g_aFixedVirtualAllocs[idxFixed].fInUse = K_TRUE;
     7555                            pvMem                           = pvAddr;
     7556                            idxPreAllocated                 = idxFixed;
     7557                            KW_LOG(("VirtualAlloc: pvAddr=%p cb=%p type=%#x prot=%#x -> %p [pre allocated]\n",
     7558                                    pvAddr, cb, fAllocType, fProt, pvMem));
     7559                            kwSandboxLogFixedAllocation(idxFixed, "kwSandbox_Kernel32_VirtualAlloc");
     7560                            SetLastError(NO_ERROR);
     7561                            break;
     7562                        }
     7563                        kwErrPrintf("VirtualAlloc: Fixed allocation at %p is already in use!\n", pvAddr);
     7564                    }
     7565                    else
     7566                        kwErrPrintf("VirtualAlloc: Fixed allocation at %p LB %#x not large enough: %#x\n",
     7567                                     pvAddr, g_aFixedVirtualAllocs[idxFixed].cbFixed, cb);
     7568                }
     7569        }
     7570        if (!pvMem)
     7571#endif
     7572        {
     7573            pvMem = VirtualAlloc(pvAddr, cb, fAllocType, fProt);
     7574            KW_LOG(("VirtualAlloc: pvAddr=%p cb=%p type=%#x prot=%#x -> %p (last=%d)\n",
     7575                    pvAddr, cb, fAllocType, fProt, pvMem, GetLastError()));
     7576            if (pvAddr && pvAddr != pvMem)
     7577                kwErrPrintf("VirtualAlloc %p LB %#x (%#x,%#x) failed: %p / %u\n",
     7578                            pvAddr, cb, fAllocType, fProt, pvMem, GetLastError());
     7579        }
     7580
     7581        if (pvMem)
     7582        {
     7583            /*
     7584             * Track it.
     7585             */
     7586            PKWVIRTALLOC pTracker;
     7587            kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
     7588
     7589            pTracker = g_Sandbox.pVirtualAllocHead;
     7590            while (   pTracker
     7591                   && (KUPTR)pvMem - (KUPTR)pTracker->pvAlloc >= pTracker->cbAlloc)
     7592                pTracker = pTracker->pNext;
     7593            if (!pTracker)
     7594            {
     7595                DWORD dwErr = GetLastError();
     7596                PKWVIRTALLOC pTracker = (PKWVIRTALLOC)kHlpAlloc(sizeof(*pTracker));
     7597                if (pTracker)
     7598                {
     7599                    pTracker->pvAlloc           = pvMem;
     7600                    pTracker->cbAlloc           = cb;
     7601                    pTracker->idxPreAllocated   = idxPreAllocated;
     7602                    pTracker->pNext             = g_Sandbox.pVirtualAllocHead;
     7603                    g_Sandbox.pVirtualAllocHead = pTracker;
     7604                }
     7605                SetLastError(dwErr);
     7606            }
     7607        }
     7608    }
     7609    else
     7610        pvMem = VirtualAlloc(pvAddr, cb, fAllocType, fProt);
    73347611    KW_LOG(("VirtualAlloc: pvAddr=%p cb=%p type=%#x prot=%#x -> %p (last=%d)\n",
    73357612            pvAddr, cb, fAllocType, fProt, pvMem, GetLastError()));
    7336     if (   g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL
    7337         && pvMem)
    7338     {
    7339         PKWVIRTALLOC pTracker;
    7340         kHlpAssert(GetCurrentThreadId() == g_Sandbox.idMainThread);
    7341 
    7342         pTracker = g_Sandbox.pVirtualAllocHead;
    7343         while (   pTracker
    7344                && (KUPTR)pvMem - (KUPTR)pTracker->pvAlloc >= pTracker->cbAlloc)
    7345             pTracker = pTracker->pNext;
    7346         if (!pTracker)
    7347         {
    7348             DWORD dwErr = GetLastError();
    7349             PKWVIRTALLOC pTracker = (PKWVIRTALLOC)kHlpAlloc(sizeof(*pTracker));
    7350             if (pTracker)
    7351             {
    7352                 pTracker->pvAlloc = pvMem;
    7353                 pTracker->cbAlloc = cb;
    7354                 pTracker->pNext   = g_Sandbox.pVirtualAllocHead;
    7355                 g_Sandbox.pVirtualAllocHead = pTracker;
    7356             }
    7357             SetLastError(dwErr);
    7358         }
    7359     }
    73607613    return pvMem;
    73617614}
     
    73657618static BOOL WINAPI kwSandbox_Kernel32_VirtualFree(PVOID pvAddr, SIZE_T cb, DWORD dwFreeType)
    73667619{
    7367     BOOL fRc = VirtualFree(pvAddr, cb, dwFreeType);
    7368     KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> %d\n", pvAddr, cb, dwFreeType, fRc));
     7620    BOOL fRc;
    73697621    if (g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL)
    73707622    {
     
    73897641                }
    73907642                if (pTracker)
    7391                     kHlpFree(pTracker);
    7392                 else
    7393                     KW_LOG(("VirtualFree: pvAddr=%p not found!\n", pvAddr));
    7394             }
    7395         }
    7396     }
     7643                {
     7644#ifdef WITH_FIXED_VIRTUAL_ALLOCS
     7645                    if (pTracker->idxPreAllocated != KU32_MAX)
     7646                    {
     7647                        kwSandboxResetFixedAllocation(pTracker->idxPreAllocated);
     7648                        KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> TRUE [pre allocated #%u]\n",
     7649                                pvAddr, cb, dwFreeType, pTracker->idxPreAllocated));
     7650                        kHlpFree(pTracker);
     7651                        return TRUE;
     7652                    }
     7653#endif
     7654
     7655                    fRc = VirtualFree(pvAddr, cb, dwFreeType);
     7656                    if (fRc)
     7657                        kHlpFree(pTracker);
     7658                    else
     7659                    {
     7660                        pTracker->pNext = g_Sandbox.pVirtualAllocHead;
     7661                        g_Sandbox.pVirtualAllocHead = pTracker;
     7662                    }
     7663                    KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> %d\n", pvAddr, cb, dwFreeType, fRc));
     7664                    return fRc;
     7665                }
     7666
     7667                KW_LOG(("VirtualFree: pvAddr=%p not found!\n", pvAddr));
     7668            }
     7669        }
     7670    }
     7671
     7672#ifdef WITH_FIXED_VIRTUAL_ALLOCS
     7673    /*
     7674     * Protect our fixed allocations (this isn't just paranoia, btw.).
     7675     */
     7676    if (dwFreeType & MEM_RELEASE)
     7677    {
     7678        KU32 idxFixed = K_ELEMENTS(g_aFixedVirtualAllocs);
     7679        while (idxFixed-- > 0)
     7680            if (g_aFixedVirtualAllocs[idxFixed].pvReserved == pvAddr)
     7681            {
     7682                KW_LOG(("VirtualFree: Damn it! Don't free g_aFixedVirtualAllocs[#%u]: %p LB %#x\n",
     7683                        idxFixed, g_aFixedVirtualAllocs[idxFixed].pvReserved, g_aFixedVirtualAllocs[idxFixed].cbFixed));
     7684                return TRUE;
     7685            }
     7686    }
     7687#endif
     7688
     7689    /*
     7690     * Not tracker or not actually free the virtual range.
     7691     */
     7692    fRc = VirtualFree(pvAddr, cb, dwFreeType);
     7693    KW_LOG(("VirtualFree: pvAddr=%p cb=%p type=%#x -> %d\n", pvAddr, cb, dwFreeType, fRc));
    73977694    return fRc;
    73987695}
     
    83988695    { TUPLE("CreateFileMappingW"),          NULL,       (KUPTR)kwSandbox_Kernel32_CreateFileMappingW },
    83998696    { TUPLE("MapViewOfFile"),               NULL,       (KUPTR)kwSandbox_Kernel32_MapViewOfFile },
     8697    { TUPLE("MapViewOfFileEx"),             NULL,       (KUPTR)kwSandbox_Kernel32_MapViewOfFileEx },
    84008698    { TUPLE("UnmapViewOfFile"),             NULL,       (KUPTR)kwSandbox_Kernel32_UnmapViewOfFile },
    84018699#endif
     
    85348832    { TUPLE("CreateFileMappingW"),          NULL,       (KUPTR)kwSandbox_Kernel32_CreateFileMappingW },
    85358833    { TUPLE("MapViewOfFile"),               NULL,       (KUPTR)kwSandbox_Kernel32_MapViewOfFile },
     8834    { TUPLE("MapViewOfFileEx"),             NULL,       (KUPTR)kwSandbox_Kernel32_MapViewOfFileEx },
    85368835    { TUPLE("UnmapViewOfFile"),             NULL,       (KUPTR)kwSandbox_Kernel32_UnmapViewOfFile },
    85378836#endif
     
    86128911        case CTRL_C_EVENT:
    86138912            fprintf(stderr, "kWorker: Ctrl-C\n");
     8913            g_fCtrlC = K_TRUE;
    86148914            exit(9);
    86158915            break;
     
    86178917        case CTRL_BREAK_EVENT:
    86188918            fprintf(stderr, "kWorker: Ctrl-Break\n");
     8919            g_fCtrlC = K_TRUE;
    86198920            exit(10);
    86208921            break;
     
    86228923        case CTRL_CLOSE_EVENT:
    86238924            fprintf(stderr, "kWorker: console closed\n");
     8925            g_fCtrlC = K_TRUE;
    86248926            exit(11);
    86258927            break;
     
    86278929        case CTRL_LOGOFF_EVENT:
    86288930            fprintf(stderr, "kWorker: logoff event\n");
     8931            g_fCtrlC = K_TRUE;
    86298932            exit(11);
    86308933            break;
     
    86328935        case CTRL_SHUTDOWN_EVENT:
    86338936            fprintf(stderr, "kWorker: shutdown event\n");
     8937            g_fCtrlC = K_TRUE;
    86348938            exit(11);
    86358939            break;
     
    90729376        PKWVIRTALLOC pNext = pTracker->pNext;
    90739377        KW_LOG(("Freeing VirtualFree leak %p LB %#x\n", pTracker->pvAlloc, pTracker->cbAlloc));
    9074         VirtualFree(pTracker->pvAlloc, 0, MEM_RELEASE);
     9378
     9379#ifdef WITH_FIXED_VIRTUAL_ALLOCS
     9380        if (pTracker->idxPreAllocated != KU32_MAX)
     9381            kwSandboxResetFixedAllocation(pTracker->idxPreAllocated);
     9382        else
     9383#endif
     9384            VirtualFree(pTracker->pvAlloc, 0, MEM_RELEASE);
    90759385        kHlpFree(pTracker);
    90769386        pTracker = pNext;
     
    983310143int main(int argc, char **argv)
    983410144{
    9835     KSIZE           cbMsgBuf = 0;
    9836     KU8            *pbMsgBuf = NULL;
    9837     int             i;
    9838     HANDLE          hPipe = INVALID_HANDLE_VALUE;
    9839     const char     *pszTmp;
    9840     KFSLOOKUPERROR  enmIgnored;
     10145    KSIZE                           cbMsgBuf = 0;
     10146    KU8                            *pbMsgBuf = NULL;
     10147    int                             i;
     10148    HANDLE                          hPipe = INVALID_HANDLE_VALUE;
     10149    const char                     *pszTmp;
     10150    KFSLOOKUPERROR                  enmIgnored;
    984110151#if defined(KBUILD_OS_WINDOWS) && defined(KBUILD_ARCH_X86)
    9842     PVOID           pvVecXcptHandler = AddVectoredExceptionHandler(0 /*called last*/, kwSandboxVecXcptEmulateChained);
     10152    PVOID                           pvVecXcptHandler = AddVectoredExceptionHandler(0 /*called last*/,
     10153                                                                                   kwSandboxVecXcptEmulateChained);
    984310154#endif
    984410155#ifdef WITH_CONSOLE_OUTPUT_BUFFERING
     
    984710158    PMY_RTL_USER_PROCESS_PARAMETERS pProcessParams = (PMY_RTL_USER_PROCESS_PARAMETERS)pPeb->ProcessParameters;
    984810159    DWORD                           dwType;
     10160#endif
     10161
     10162
     10163#ifdef WITH_FIXED_VIRTUAL_ALLOCS
     10164    /*
     10165     * Reserve memory for cl.exe
     10166     */
     10167    for (i = 0; i < K_ELEMENTS(g_aFixedVirtualAllocs); i++)
     10168    {
     10169        g_aFixedVirtualAllocs[i].fInUse     = K_FALSE;
     10170        g_aFixedVirtualAllocs[i].pvReserved = VirtualAlloc((void *)g_aFixedVirtualAllocs[i].uFixed,
     10171                                                           g_aFixedVirtualAllocs[i].cbFixed,
     10172                                                           MEM_RESERVE, PAGE_READWRITE);
     10173        if (   !g_aFixedVirtualAllocs[i].pvReserved
     10174            || g_aFixedVirtualAllocs[i].pvReserved != (void *)g_aFixedVirtualAllocs[i].uFixed)
     10175        {
     10176            kwErrPrintf("Failed to reserve %p LB %#x: %u\n", g_aFixedVirtualAllocs[i].uFixed, g_aFixedVirtualAllocs[i].cbFixed,
     10177                        GetLastError());
     10178            if (g_aFixedVirtualAllocs[i].pvReserved)
     10179            {
     10180                VirtualFree(g_aFixedVirtualAllocs[i].pvReserved, g_aFixedVirtualAllocs[i].cbFixed, MEM_RELEASE);
     10181                g_aFixedVirtualAllocs[i].pvReserved = NULL;
     10182            }
     10183        }
     10184    }
    984910185#endif
    985010186
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