VirtualBox

Changeset 52018 in vbox for trunk/src


Ignore:
Timestamp:
Jul 14, 2014 7:44:01 PM (11 years ago)
Author:
vboxsync
Message:

IPRT: Make RTMemSafer use the SUPR3 page allocation if available to allocate locked down memory. Change API to make allocation strategy tweakable to allow for pageable allocations where the support library is not available (build tools like bldRTSignTool) while still making sure the memory is non-pageable for sensitive data

Location:
trunk/src/VBox/Runtime
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/math/bignum.cpp

    r51915 r52018  
    118118    Assert(cbNew > cbOld);
    119119
    120     void *pvNew;
     120    void *pvNew = NULL;
    121121    if (pBigNum->fSensitive)
    122         pvNew = RTMemSaferReallocZ(cbOld, pBigNum->pauElements, cbNew);
     122    {
     123        int rc = RTMemSaferReallocZEx(cbOld, pBigNum->pauElements, cbNew, &pvNew, RTMEMSAFER_ALLOC_EX_ALLOW_PAGEABLE_BACKING);
     124        Assert(VALID_PTR(pvNew) || RT_FAILURE(rc));
     125    }
    123126    else
    124127        pvNew = RTMemRealloc(pBigNum->pauElements, cbNew);
     
    323326        pBigNum->cAllocated = RT_ALIGN_32(pBigNum->cUsed, 4);
    324327        if (pBigNum->fSensitive)
    325             pBigNum->pauElements = (RTBIGNUMELEMENT *)RTMemSaferAllocZ(pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE);
     328        {
     329            int rc = RTMemSaferAllocZEx((void **)&pBigNum->pauElements, pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE,
     330                                        RTMEMSAFER_ALLOC_EX_ALLOW_PAGEABLE_BACKING);
     331            Assert(VALID_PTR(pBigNum->pauElements) || RT_FAILURE(rc));
     332        }
    326333        else
    327334            pBigNum->pauElements = (RTBIGNUMELEMENT *)RTMemAlloc(pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE);
     
    457464        pBigNum->cAllocated = RT_ALIGN_32(pBigNum->cUsed, 4);
    458465        if (pBigNum->fSensitive)
    459             pBigNum->pauElements = (RTBIGNUMELEMENT *)RTMemSaferAllocZ(pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE);
     466        {
     467            rc = RTMemSaferAllocZEx((void **)&pBigNum->pauElements, pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE,
     468                                    RTMEMSAFER_ALLOC_EX_ALLOW_PAGEABLE_BACKING);
     469            Assert(VALID_PTR(pBigNum->pauElements) || RT_FAILURE(rc));
     470        }
    460471        else
    461472            pBigNum->pauElements = (RTBIGNUMELEMENT *)RTMemAlloc(pBigNum->cAllocated * RTBIGNUM_ELEMENT_SIZE);
  • trunk/src/VBox/Runtime/generic/memsafer-generic.cpp

    r51916 r52018  
    3434#include <iprt/assert.h>
    3535#include <iprt/string.h>
     36#if defined(IN_SUP_R3) && defined(VBOX) && !defined(RT_NO_GIP)
     37# include <iprt/param.h>
     38# include <VBox/sup.h>
     39#endif /* IN_SUP_R3 */
    3640
    3741
     
    4650#define RTMEMSAFER_PAD_AFTER    32
    4751
     52/*******************************************************************************
     53*   Structures and Typedefs                                                    *
     54*******************************************************************************/
     55
     56/**
     57 * Supported allocation methods.
     58 */
     59typedef enum RTMEMSAFERALLOCMETHOD
     60{
     61    /** Invalid method. */
     62    RTMEMSAFERALLOCMETHOD_INVALID = 0,
     63    /** RTMem{Alloc|Free} methods, least secure!. */
     64    RTMEMSAFERALLOCMETHOD_RTMEM,
     65    /** Support library. */
     66    RTMEMSAFERALLOCMETHOD_SUPR3,
     67    /** 32bit hack. */
     68    RTMEMSAFERALLOCMETHOD_32BIT_HACK = 0x7fffffff
     69} RTMEMSAFERALLOCMETHOD;
     70/** Pointer to a allocation method enum. */
     71typedef RTMEMSAFERALLOCMETHOD *PRTMEMSAFERALLOCMETHOD;
     72
     73/**
     74 * Memory header for safer memory allocations.
     75 *
     76 * @note: There is no magic value used deliberately to make identifying this structure
     77 *        as hard as possible.
     78 */
     79typedef struct RTMEMSAFERHDR
     80{
     81    /** Flags passed to this allocation - used for freeing and reallocation. */
     82    uint32_t              fFlags;
     83    /** Allocation method used. */
     84    RTMEMSAFERALLOCMETHOD enmAllocMethod;
     85    /** Amount of bytes allocated. */
     86    size_t                cb;
     87} RTMEMSAFERHDR;
     88/** Pointer to a safer memory header. */
     89typedef RTMEMSAFERHDR *PRTMEMSAFERHDR;
     90/** Make sure we are staying in the padding area. */
     91AssertCompile(sizeof(RTMEMSAFERHDR) < RTMEMSAFER_PAD_BEFORE);
    4892
    4993/*******************************************************************************
    5094*   Global Variables                                                           *
    5195*******************************************************************************/
    52 /** XOR scrabler value.
     96/** XOR scrambler value.
    5397 * @todo determine this at runtime */
    5498#if ARCH_BITS == 32
     
    62106
    63107
     108/**
     109 * Support (SUPR3) based allocator.
     110 *
     111 * @returns VBox status code.
     112 * @retval VERR_NOT_SUPPORTED if this allocation method is not supported in this
     113 *         version of the library.
     114 * @param  ppvNew    Where to store the pointer to the new buffer on success.
     115 * @param  cb        Amount of bytes to allocate.
     116 *
     117 * @note: The allocation will have an extra page allocated before and after the
     118 *        user area with all access rights removed to prevent heartbleed like
     119 *        attacks.
     120 */
     121static int rtMemSaferSupR3Alloc(void **ppvNew, size_t cb)
     122{
     123#if defined(IN_SUP_R3) && defined(VBOX) && !defined(RT_NO_GIP)
     124    /*
     125     * Allocate locked memory from the support library.
     126     *
     127     */
     128    size_t cbUser = RT_ALIGN_Z(cb, PAGE_SIZE);
     129    size_t cPages = cbUser / PAGE_SIZE + 2; /* For the extra guarding pages. */
     130    void *pvNew = NULL;
     131    int rc = SUPR3PageAllocEx(cPages, 0 /* fFlags */, &pvNew, NULL /* pR0Ptr */, NULL /* paPages */);
     132    if (RT_SUCCESS(rc))
     133    {
     134        /* Change the memory protection of the pages guarding the allocation. */
     135        rc = SUPR3PageProtect(pvNew, NIL_RTR0PTR, 0, PAGE_SIZE, RTMEM_PROT_NONE);
     136        if (RT_SUCCESS(rc))
     137        {
     138            rc = SUPR3PageProtect(pvNew, NIL_RTR0PTR, PAGE_SIZE + cbUser, PAGE_SIZE, RTMEM_PROT_NONE);
     139            if (RT_SUCCESS(rc))
     140            {
     141                *ppvNew = (uint8_t *)pvNew + PAGE_SIZE;
     142                return VINF_SUCCESS;
     143            }
     144        }
     145
     146        rc = SUPR3PageFreeEx(pvNew, cPages);
     147        AssertRC(rc);
     148    }
     149
     150    return rc;
     151#else
     152    return VERR_NOT_SUPPORTED;
     153#endif
     154}
     155
     156
     157/**
     158 * Free method for memory allocated using the Support (SUPR3) based allocator.
     159 *
     160 * @returns nothing.
     161 * @param   pv    Pointer to the memory to free.
     162 * @param   cb    Amount of bytes allocated.
     163 */
     164static void rtMemSafeSupR3Free(void *pv, size_t cb)
     165{
     166#if defined(IN_SUP_R3) && defined(VBOX) && !defined(RT_NO_GIP)
     167    size_t cbUser = RT_ALIGN_Z(cb, PAGE_SIZE);
     168    size_t cPages = cbUser / PAGE_SIZE + 2; /* For the extra pages. */
     169    void *pvStart = (uint8_t *)pv - PAGE_SIZE;
     170
     171    int rc = SUPR3PageFreeEx(pvStart, cPages);
     172    AssertRC(rc);
     173#else
     174    AssertMsgFailed(("SUPR3 allocated memory but freeing is not supported, messed up\n"));
     175#endif
     176}
     177
     178
    64179RTDECL(int) RTMemSaferScramble(void *pv, size_t cb)
    65180{
    66 
    67     AssertMsg(*(size_t *)((char *)pv - RTMEMSAFER_PAD_BEFORE) == cb,
    68               ("*pvStart=%#zx cb=%#zx\n", *(size_t *)((char *)pv- RTMEMSAFER_PAD_BEFORE), cb));
     181    PRTMEMSAFERHDR pHdr = (PRTMEMSAFERHDR)((char *)pv - RTMEMSAFER_PAD_BEFORE);
     182    AssertMsg(pHdr->cb == cb, ("pHdr->cb=%#zx cb=%#zx\n", pHdr->cb, cb));
    69183
    70184    /* Note! This isn't supposed to be safe, just less obvious. */
     
    85199RTDECL(int) RTMemSaferUnscramble(void *pv, size_t cb)
    86200{
    87     AssertMsg(*(size_t *)((char *)pv - RTMEMSAFER_PAD_BEFORE) == cb,
    88               ("*pvStart=%#zx cb=%#zx\n", *(size_t *)((char *)pv - RTMEMSAFER_PAD_BEFORE), cb));
     201    PRTMEMSAFERHDR pHdr = (PRTMEMSAFERHDR)((char *)pv - RTMEMSAFER_PAD_BEFORE);
     202    AssertMsg(pHdr->cb == cb, ("pHdr->cb=%#zx cb=%#zx\n", pHdr->cb, cb));
    89203
    90204    /* Note! This isn't supposed to be safe, just less obvious. */
     
    103217
    104218
    105 RTDECL(int) RTMemSaferAllocZExTag(void **ppvNew, size_t cb, const char *pszTag) RT_NO_THROW
     219RTDECL(int) RTMemSaferAllocZExTag(void **ppvNew, size_t cb, uint32_t fFlags, const char *pszTag) RT_NO_THROW
    106220{
    107221    AssertReturn(cb, VERR_INVALID_PARAMETER);
     
    111225    /*
    112226     * Don't request zeroed memory.  We want random heap garbage in the
    113      * padding zones, notthing that makes our allocations easier to find.
     227     * padding zones, nothing that makes our allocations easier to find.
    114228     */
     229    RTMEMSAFERALLOCMETHOD enmAllocMethod = RTMEMSAFERALLOCMETHOD_SUPR3;
    115230    size_t cbUser = RT_ALIGN_Z(cb, RTMEMSAFER_ALIGN);
    116     void *pvNew = RTMemAlloc(cbUser + RTMEMSAFER_PAD_BEFORE + RTMEMSAFER_PAD_AFTER);
     231    void *pvNew = NULL;
     232    int rc = rtMemSaferSupR3Alloc(&pvNew, cbUser + RTMEMSAFER_PAD_BEFORE + RTMEMSAFER_PAD_AFTER);
     233    if (   RT_FAILURE(rc)
     234        && fFlags & RTMEMSAFER_ALLOC_EX_ALLOW_PAGEABLE_BACKING)
     235    {
     236        /* Pageable memory allowed. */
     237        enmAllocMethod = RTMEMSAFERALLOCMETHOD_RTMEM;
     238        pvNew = RTMemAlloc(cbUser + RTMEMSAFER_PAD_BEFORE + RTMEMSAFER_PAD_AFTER);
     239    }
     240
    117241    if (pvNew)
    118242    {
    119 #ifdef RT_STRICT /* For checking input in string builds. */
    120         memset(pvNew, 0xad, RTMEMSAFER_PAD_BEFORE);
     243        PRTMEMSAFERHDR pHdr = (PRTMEMSAFERHDR)pvNew;
     244        pHdr->fFlags         = fFlags;
     245        pHdr->cb             = cb;
     246        pHdr->enmAllocMethod = enmAllocMethod;
     247#ifdef RT_STRICT /* For checking input in strict builds. */
     248        memset((char *)pvNew + sizeof(RTMEMSAFERHDR), 0xad, RTMEMSAFER_PAD_BEFORE - sizeof(RTMEMSAFERHDR));
    121249        memset((char *)pvNew + RTMEMSAFER_PAD_BEFORE + cb, 0xda, RTMEMSAFER_PAD_AFTER + (cbUser - cb));
    122         *(size_t *)pvNew = cb;
    123250#endif
    124251
     
    131258        return VINF_SUCCESS;
    132259    }
    133     return VERR_NO_MEMORY;
     260    return rc;
    134261}
    135262RT_EXPORT_SYMBOL(RTMemSaferAllocZExTag);
     
    141268    {
    142269        Assert(cb);
     270
     271        size_t cbUser = RT_ALIGN_Z(cb, RTMEMSAFER_ALIGN);
    143272        void *pvStart = (char *)pv - RTMEMSAFER_PAD_BEFORE;
    144         AssertMsg(*(size_t *)pvStart == cb, ("*pvStart=%#zx cb=%#zx\n", *(size_t *)pvStart, cb));
     273        PRTMEMSAFERHDR pHdr = (PRTMEMSAFERHDR)pvStart;
     274        AssertMsg(pHdr->cb == cb, ("pHdr->cb=%#zx cb=%#zx\n", pHdr->cb, cb));
     275
    145276        RTMemWipeThoroughly(pv, RT_ALIGN_Z(cb, RTMEMSAFER_ALIGN), 3);
    146         RTMemFree(pvStart);
     277
     278        switch (pHdr->enmAllocMethod)
     279        {
     280            case RTMEMSAFERALLOCMETHOD_SUPR3:
     281                rtMemSafeSupR3Free(pvStart, cbUser + RTMEMSAFER_PAD_BEFORE + RTMEMSAFER_PAD_AFTER);
     282                break;
     283            case RTMEMSAFERALLOCMETHOD_RTMEM:
     284                RTMemFree(pvStart);
     285                break;
     286            default:
     287                AssertMsgFailed(("Invalid allocation method, corrupted header\n"));
     288        }
    147289    }
    148290    else
     
    152294
    153295
    154 RTDECL(int) RTMemSaferReallocZExTag(size_t cbOld, void *pvOld, size_t cbNew, void **ppvNew, const char *pszTag) RT_NO_THROW
     296RTDECL(int) RTMemSaferReallocZExTag(size_t cbOld, void *pvOld, size_t cbNew, void **ppvNew, uint32_t fFlags, const char *pszTag) RT_NO_THROW
    155297{
    156298    /*
     
    163305    if (cbNew && cbOld)
    164306    {
     307        PRTMEMSAFERHDR pHdr = (PRTMEMSAFERHDR)((char *)pvOld - RTMEMSAFER_PAD_BEFORE);
    165308        AssertPtr(pvOld);
    166309        AssertMsg(*(size_t *)((char *)pvOld - RTMEMSAFER_PAD_BEFORE) == cbOld,
     
    168311
    169312        void *pvNew;
    170         rc = RTMemSaferAllocZExTag(&pvNew, cbNew, pszTag);
     313        rc = RTMemSaferAllocZExTag(&pvNew, cbNew, pHdr->fFlags, pszTag);
    171314        if (RT_SUCCESS(rc))
    172315        {
     
    180323    {
    181324        Assert(pvOld == NULL);
    182         rc = RTMemSaferAllocZExTag(ppvNew, cbNew, pszTag);
     325        rc = RTMemSaferAllocZExTag(ppvNew, cbNew, fFlags, pszTag);
    183326    }
    184327    /* Free operation*/
     
    196339{
    197340    void *pvNew = NULL;
    198     int rc = RTMemSaferAllocZExTag(&pvNew, cb, pszTag);
     341    int rc = RTMemSaferAllocZExTag(&pvNew, cb, RTMEMSAFER_ALLOC_EX_FLAGS_DEFAULT, pszTag);
    199342    if (RT_SUCCESS(rc))
    200343        return pvNew;
     
    207350{
    208351    void *pvNew = NULL;
    209     int rc = RTMemSaferReallocZExTag(cbOld, pvOld, cbNew, &pvNew, pszTag);
     352    int rc = RTMemSaferReallocZExTag(cbOld, pvOld, cbNew, &pvNew, RTMEMSAFER_ALLOC_EX_FLAGS_DEFAULT, pszTag);
    210353    if (RT_SUCCESS(rc))
    211354        return pvNew;
  • trunk/src/VBox/Runtime/testcase/Makefile.kmk

    r51906 r52018  
    9090        tstRTMemPool \
    9191        tstRTMemWipe \
     92        tstRTMemSafer \
    9293        tstMove \
    9394        tstRTMp-1 \
     
    456457tstRTMemWipe_SOURCES = tstRTMemWipe.cpp
    457458
     459tstRTMemSafer_TEMPLATE = VBOXR3TSTEXE
     460tstRTMemSafer_SOURCES = tstRTMemSafer.cpp
     461
    458462tstMove_TEMPLATE = VBOXR3TSTEXE
    459463tstMove_SOURCES = tstMove.cpp
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