VirtualBox

Changeset 101142 in vbox


Ignore:
Timestamp:
Sep 18, 2023 11:12:16 AM (16 months ago)
Author:
vboxsync
Message:

IPRT/mem: Added a RTMEMPAGEALLOC_F_EXECUTABLE to RTMemPageAllocEx. Untested on windows. bugref:10370

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/mem.h

    r98103 r101142  
    507507/** Try prevent the memory from ending up in a dump/core. */
    508508#define RTMEMPAGEALLOC_F_ADVISE_NO_DUMP RT_BIT_32(2)
     509/** Allocate pages that are readable, writeable and executable.
     510 * @note This may fail on some platforms for security policy reasons. */
     511#define RTMEMPAGEALLOC_F_EXECUTABLE     RT_BIT_32(3)
    509512/** Valid bit mask. */
    510 #define RTMEMPAGEALLOC_F_VALID_MASK     UINT32_C(0x00000007)
     513#define RTMEMPAGEALLOC_F_VALID_MASK     UINT32_C(0x0000000f)
    511514/** @} */
    512515
  • trunk/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-heap-posix.cpp

    r99779 r101142  
    550550
    551551/**
    552  * Allocates one or more pages off the heap.
     552 * Frees an allocation.
    553553 *
    554554 * @returns IPRT status code.
     555 * @retval  VERR_NOT_FOUND if pv isn't within any of the memory blocks in the
     556 *          heap.
     557 * @retval  VERR_INVALID_POINTER if the given memory range isn't exactly one
     558 *          allocation block.
    555559 * @param   pHeap           The page heap.
    556560 * @param   pv              Pointer to what RTHeapPageAlloc returned.
     
    652656        }
    653657        else
    654             rc = VERR_INVALID_POINTER;
     658            rc = VERR_NOT_FOUND; /* Distinct return code for this so rtMemPagePosixFree and others can try alternative heaps. */
    655659
    656660        RTCritSectLeave(&pHeap->CritSect);
     
    737741 * Free memory allocated by rtMemPagePosixAlloc.
    738742 *
    739  * @param   pv                  The address of the memory to free.
    740  * @param   cb                  The size.
    741  * @param   pHeap               The heap.
    742  */
    743 static void rtMemPagePosixFree(void *pv, size_t cb, PRTHEAPPAGE pHeap)
     743 * @param   pv      The address of the memory to free.
     744 * @param   cb      The size.
     745 * @param   pHeap1  The most probable heap.
     746 * @param   pHeap2  The less probable heap.
     747 */
     748static void rtMemPagePosixFree(void *pv, size_t cb, PRTHEAPPAGE pHeap1, PRTHEAPPAGE pHeap2)
    744749{
    745750    /*
     
    763768    else
    764769    {
    765         int rc = RTHeapPageFree(pHeap, pv, cb >> PAGE_SHIFT);
     770        int rc = RTHeapPageFree(pHeap1, pv, cb >> PAGE_SHIFT);
     771        if (rc == VERR_NOT_FOUND)
     772            rc = RTHeapPageFree(pHeap2, pv, cb >> PAGE_SHIFT);
    766773        AssertRC(rc);
    767774    }
     
    787794{
    788795    AssertReturn(!(fFlags & ~RTMEMPAGEALLOC_F_VALID_MASK), NULL);
    789     return rtMemPagePosixAlloc(cb, pszTag, fFlags, &g_MemPagePosixHeap);
     796    return rtMemPagePosixAlloc(cb, pszTag, fFlags,
     797                               !(fFlags & RTMEMPAGEALLOC_F_EXECUTABLE) ? &g_MemPagePosixHeap : &g_MemExecPosixHeap);
    790798}
    791799
     
    793801RTDECL(void) RTMemPageFree(void *pv, size_t cb) RT_NO_THROW_DEF
    794802{
    795     return rtMemPagePosixFree(pv, cb, &g_MemPagePosixHeap);
    796 }
    797 
     803    rtMemPagePosixFree(pv, cb, &g_MemPagePosixHeap, &g_MemExecPosixHeap);
     804}
     805
  • trunk/src/VBox/Runtime/r3/posix/rtmempage-exec-mmap-posix.cpp

    r100310 r101142  
    173173{
    174174    AssertReturn(!(fFlags & ~RTMEMPAGEALLOC_F_VALID_MASK), NULL);
    175     return rtMemPagePosixAlloc(cb, pszTag, fFlags, 0);
     175    return rtMemPagePosixAlloc(cb, pszTag, fFlags, !(fFlags & RTMEMPAGEALLOC_F_EXECUTABLE) ? 0 : PROT_EXEC);
    176176}
    177177
  • trunk/src/VBox/Runtime/r3/win/alloc-win.cpp

    r98103 r101142  
    5656
    5757
     58/** @todo merge the page alloc code with the heap-based mmap stuff as
     59 *        _aligned_malloc just isn't well suited for exec. */
     60
     61
    5862RTDECL(void *) RTMemPageAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
    5963{
     
    7781
    7882#ifdef USE_VIRTUAL_ALLOC
    79     void *pv = VirtualAlloc(NULL, cbAligned, MEM_COMMIT, PAGE_READWRITE);
     83    void *pv = VirtualAlloc(NULL, cbAligned, MEM_COMMIT,
     84                            !(fFlags & RTMEMPAGEALLOC_F_EXECUTABLE) ? PAGE_READWRITE : PAGE_EXECUTE_READWRITE);
    8085#else
    8186    void *pv = _aligned_malloc(cbAligned, PAGE_SIZE);
    8287#endif
    8388    AssertMsgReturn(pv, ("cb=%d lasterr=%d\n", cb, GetLastError()), NULL);
     89
     90#ifdef USE_VIRTUAL_ALLOC
     91    if (fFlags & RTMEMPAGEALLOC_F_EXECUTABLE)
     92    {
     93        DWORD      fIgn = 0;
     94        BOOL const fRc  = VirtualProtect(pv, cbAligned, PAGE_EXECUTE_READWRITE, &fIgn);
     95        AssertMsgReturnStmt(fRc, ("%p LB %#zx: %#u\n", pv, cbAligned, GetLastError()), _aligned_free(pv), NULL);
     96    }
     97#endif
    8498
    8599    if (fFlags & RTMEMPAGEALLOC_F_ADVISE_LOCKED)
     
    127141            AssertMsgFailed(("pv=%p lasterr=%d\n", pv, GetLastError()));
    128142#else
     143        /** @todo The exec version of this doesn't really work well... */
     144        MEMORY_BASIC_INFORMATION MemInfo = { NULL }
     145        SIZE_T cbRet = VirtualQuery(pv, &MemInfo, cb);
     146        Assert(cbRet > 0)
     147        if (cbRet >= 0 && MemInfo.Protect == PAGE_EXECUTE_READWRITE)
     148        {
     149            DWORD      fIgn = 0;
     150            BOOL const fRc  = VirtualProtect(pv, cb, PAGE_READWRITE, &fIgn);
     151            Assert(fRc); RT_NOREF(fRc);
     152        }
    129153        _aligned_free(pv);
    130154#endif
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