VirtualBox

Changeset 97188 in vbox


Ignore:
Timestamp:
Oct 18, 2022 7:42:50 AM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154163
Message:

Support/SUPR3HardenedEntitlementsVM.plist,VMM/NEMR3Native-darwin: Remove the Catalina workaround, as it turns out setting the com.apple.security.cs.allow-unsigned-executable-memory and com.apple.security.cs.disable-executable-page-protection entitlements are enough to make it work, bugref:9044

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPR3HardenedEntitlementsVM.plist

    r97177 r97188  
    44<dict>
    55    <!-- <key>com.apple.security.cs.allow-jit</key>                          <true/> -->
    6     <!-- <key>com.apple.security.cs.allow-unsigned-executable-memory</key>   <true/> -->
    7     <!-- <key>com.apple.security.cs.disable-executable-page-protection</key> <true/> -->
     6    <!--
     7      The following two entitlements are required for using AppleHV on Catalina.
     8      The first entitlement allows us to have unsigned executable memory in the guests
     9      address space like the BIOS code (and essentially all the guests address space which
     10      is mapped as RWX).
     11      The second entitlement is required in order to map guest memory as RWX into the
     12      guests address space.
     13      These entitlements are not required starting with BigSur+ where Apple has clearly
     14      changed something in their entitlement scheme without properly documenting it.
     15    -->
     16    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>   <true/>
     17    <key>com.apple.security.cs.disable-executable-page-protection</key> <true/>
    818    <!-- For audio input -->
    919    <key>com.apple.security.device.audio-input</key>                    <true/>
  • trunk/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h

    r97183 r97188  
    94239423     */
    94249424    NEMHCDARWINHMACPCCSTATE State = { RT_BOOL(pVmxTransient->uExitQual & VMX_EXIT_QUAL_EPT_ACCESS_WRITE),
    9425                                       RT_BOOL(pVmxTransient->uExitQual & VMX_EXIT_QUAL_EPT_ACCESS_INSTR_FETCH),
    94269425                                      false,
    94279426                                      false };
  • trunk/src/VBox/VMM/VMMR3/NEMR3.cpp

    r97175 r97188  
    101101                                  "|VmxPleWindow"
    102102                                  "|VmxLbr"
    103                                   "|CatalinaWxWorkaround"
    104103#endif
    105104                                  ,
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp

    r97174 r97188  
    293293/** VMX: Set if swapping EFER is supported.  */
    294294static bool             g_fHmVmxSupportsVmcsEfer = false;
    295 /** Flag whether the AppleHV code suffers from a bug preventing WX mappings and we need to
    296  * ping pong between RX and RW mappings depending on what the guest is doing. */
    297 static bool             g_fAppleHvNoWX = false;
    298295/** @name APIs imported from Hypervisor.framework.
    299296 * @{ */
     
    562559    if (fPageProt & NEM_PAGE_PROT_WRITE)
    563560        fHvMemProt |= HV_MEMORY_WRITE;
    564     if (   fPageProt & NEM_PAGE_PROT_EXECUTE
    565         && (   !g_fAppleHvNoWX
    566             || !(fPageProt & NEM_PAGE_PROT_WRITE)))
     561    if (fPageProt & NEM_PAGE_PROT_EXECUTE)
    567562        fHvMemProt |= HV_MEMORY_EXEC;
    568563
    569564    hv_return_t hrc;
    570 #if 0 /* Simulates the error path on Catalina without requiring signed binaries. */
    571     if (   (fHvMemProt & HV_MEMORY_WRITE)
    572         && (fHvMemProt & HV_MEMORY_EXEC))
    573         hrc = HV_ERROR;
    574     else
    575     {
    576         if (pVM->nem.s.fCreatedAsid)
    577             hrc = hv_vm_map_space(pVM->nem.s.uVmAsid, pvRam, GCPhys, cb, fHvMemProt);
    578         else
    579             hrc = hv_vm_map(pvRam, GCPhys, cb, fHvMemProt);
    580     }
    581 #else
    582565    if (pVM->nem.s.fCreatedAsid)
    583566        hrc = hv_vm_map_space(pVM->nem.s.uVmAsid, pvRam, GCPhys, cb, fHvMemProt);
    584567    else
    585568        hrc = hv_vm_map(pvRam, GCPhys, cb, fHvMemProt);
    586 #endif
    587569    if (hrc == HV_SUCCESS)
    588570    {
     
    594576    }
    595577
    596     if (   hrc == HV_ERROR
    597         && (fHvMemProt & HV_MEMORY_WRITE)
    598         && (fHvMemProt & HV_MEMORY_EXEC))
    599     {
    600         /*
    601          * On Catalina 10.15.7 it is impossible to have WX permissions with a properly signed
    602          * process due to some bug(?), it works starting with BigSur. So to work around that
    603          * we will never have WX mappings but only RW and RX and switch between them on demand for the
    604          * guest region in question. This can have a huge negative performance impact if the guest
    605          * writes to the same page frequently and executes code there.
    606          */
    607         Assert(!g_fAppleHvNoWX); /* We should come here only once. */
    608 
    609         /*
    610          * Try unmapping the region first (the code on Catalina doesn't remove it form the map if vm_map_protect() fails and
    611          * causes the following hv_vm_map call to fail...).
    612          */
    613         hv_vm_unmap(GCPhys, cb);
    614 
    615          /* Start with an RW mapping (most of the time the guest needs to write something there before it can execute code). */
    616         fHvMemProt &= ~HV_MEMORY_EXEC;
    617         g_fAppleHvNoWX = true;
    618         LogRel(("NEM: AppleHV refuses RWX mappings for the guest, activating workaround, expect decreased performance\n"));
    619         if (pVM->nem.s.fCreatedAsid)
    620             hrc = hv_vm_map_space(pVM->nem.s.uVmAsid, pvRam, GCPhys, cb, fHvMemProt);
    621         else
    622             hrc = hv_vm_map(pvRam, GCPhys, cb, fHvMemProt);
    623         if (hrc == HV_SUCCESS)
    624         {
    625             if (pu2State)
    626                 *pu2State = NEM_DARWIN_PAGE_STATE_WRITABLE; /* Writable without exec. */
    627             return VINF_SUCCESS;
    628         }
    629     }
    630 
    631578    return nemR3DarwinHvSts2Rc(hrc);
    632579}
    633580
    634 
     581#if 0 /* unused */
    635582DECLINLINE(int) nemR3DarwinProtectPage(PVM pVM, RTGCPHYS GCPhys, size_t cb, uint32_t fPageProt)
    636583{
    637     Assert(   !g_fAppleHvNoWX
    638            || (   (fPageProt & NEM_PAGE_PROT_WRITE)
    639                && !(fPageProt & NEM_PAGE_PROT_EXECUTE))
    640            || (   !(fPageProt & NEM_PAGE_PROT_WRITE)
    641                && (fPageProt & NEM_PAGE_PROT_EXECUTE)));
    642 
    643584    hv_memory_flags_t fHvMemProt = 0;
    644585    if (fPageProt & NEM_PAGE_PROT_READ)
     
    657598    return nemR3DarwinHvSts2Rc(hrc);
    658599}
    659 
     600#endif
    660601
    661602DECLINLINE(int) nemR3NativeGCPhys2R3PtrReadOnly(PVM pVM, RTGCPHYS GCPhys, const void **ppv)
     
    12101151/**
    12111152 * State to pass between vmxHCExitEptViolation
    1212  * and nemHCWinHandleMemoryAccessPageCheckerCallback.
     1153 * and nemR3DarwinHandleMemoryAccessPageCheckerCallback.
    12131154 */
    12141155typedef struct NEMHCDARWINHMACPCCSTATE
     
    12161157    /** Input: Write access. */
    12171158    bool    fWriteAccess;
    1218     /** Input: Instruction fetch access. */
    1219     bool    fInsnFetch;
    12201159    /** Output: Set if we did something. */
    12211160    bool    fDidSomething;
     
    12641203
    12651204            int rc = VINF_SUCCESS;
    1266             if (   pInfo->fNemProt & NEM_PAGE_PROT_WRITE
    1267                 && !pState->fInsnFetch)
     1205            if (pInfo->fNemProt & NEM_PAGE_PROT_WRITE)
    12681206            {
    12691207                void *pvPage;
    12701208                rc = nemR3NativeGCPhys2R3PtrWriteable(pVM, GCPhys, &pvPage);
    12711209                if (RT_SUCCESS(rc))
    1272                 {
    1273                     uint32_t fProt = pInfo->fNemProt;
    1274                     if (g_fAppleHvNoWX)
    1275                         fProt &= ~NEM_PAGE_PROT_EXECUTE; /* Start with RW mapping. */
    1276                     rc = nemR3DarwinMap(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, pvPage, X86_PAGE_SIZE, fProt, &u2State);
    1277                 }
     1210                    rc = nemR3DarwinMap(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, pvPage, X86_PAGE_SIZE, pInfo->fNemProt, &u2State);
    12781211            }
    12791212            else if (pInfo->fNemProt & NEM_PAGE_PROT_READ)
     
    12821215                rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhys, &pvPage);
    12831216                if (RT_SUCCESS(rc))
    1284                     rc = nemR3DarwinMap(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, pvPage, X86_PAGE_SIZE, pInfo->fNemProt & ~NEM_PAGE_PROT_WRITE, &u2State);
     1217                    rc = nemR3DarwinMap(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, pvPage, X86_PAGE_SIZE, pInfo->fNemProt, &u2State);
    12851218            }
    12861219            else /* Only EXECUTE doesn't work. */
     
    12951228        }
    12961229        case NEM_DARWIN_PAGE_STATE_READABLE:
    1297             if (   g_fAppleHvNoWX
    1298                 && pState->fWriteAccess
    1299                 && (pInfo->fNemProt & NEM_PAGE_PROT_WRITE))
    1300             {
    1301                 /* Write access to an RWX page which we set to RX due to Catalina woes, convert to RW. */
    1302                 int rc = nemR3DarwinProtectPage(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, X86_PAGE_SIZE, NEM_PAGE_PROT_READ | NEM_PAGE_PROT_WRITE);
    1303 
    1304                 pInfo->u2NemState = NEM_DARWIN_PAGE_STATE_WRITABLE;
    1305                 Log4(("nemR3DarwinHandleMemoryAccessPageCheckerCallback: %RGp - RX => RW + %Rrc\n", GCPhys, rc));
    1306                 pState->fDidSomething = true;
    1307                 /*
    1308                  * We will emulate that single instruction in case the instruction writes to the same page as it executes from to avoid
    1309                  * an endless loop switching between RW and RX mappings without making any progress.
    1310                  */
    1311                 pState->fCanResume    = false;
    1312                 return rc;
    1313             }
    1314 
    13151230            if (   !(pInfo->fNemProt & NEM_PAGE_PROT_WRITE)
    13161231                && (pInfo->fNemProt & (NEM_PAGE_PROT_READ | NEM_PAGE_PROT_EXECUTE)))
     
    13231238
    13241239        case NEM_DARWIN_PAGE_STATE_WRITABLE:
    1325             if (   g_fAppleHvNoWX
    1326                 && pState->fInsnFetch
    1327                 && (pInfo->fNemProt & NEM_PAGE_PROT_EXECUTE))
    1328             {
    1329                 /* Write access to an RWX page which we set to RW due to Catalina woes, convert to RX. */
    1330                 int rc = nemR3DarwinProtectPage(pVM, GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, X86_PAGE_SIZE, NEM_PAGE_PROT_READ | NEM_PAGE_PROT_EXECUTE);
    1331 
    1332                 pInfo->u2NemState = NEM_DARWIN_PAGE_STATE_READABLE;
    1333                 Log4(("nemR3DarwinHandleMemoryAccessPageCheckerCallback: %RGp - RW => RX + %Rrc\n", GCPhys, rc));
    1334                 pState->fDidSomething = true;
    1335                 /* Just resume with execution, no emulation in case the instruction being executed is something we don't emulate right now (AVX for example). */
    1336                 pState->fCanResume    = true;
    1337                 return rc;
    1338             }
    1339 
    13401240            if (pInfo->fNemProt & NEM_PAGE_PROT_WRITE)
    13411241            {
     
    13451245                return VINF_SUCCESS;
    13461246            }
    1347 
    13481247            break;
    13491248
     
    29932892     * useful while debugging and enabling it causes a noticeable performance hit. */
    29942893    rc = CFGMR3QueryBoolDef(pCfgNem, "VmxLbr", &pVM->nem.s.fLbr, false);
    2995     AssertRCReturn(rc, rc);
    2996 
    2997     /** @cfgm{/NEM/CatalinaWxWorkaround, bool, false}
    2998      * Whether to allow only W^X guest mappings due to a bug in the Catalina AppleHV
    2999      * driver refusing RWX when a properly signed binary is used.
    3000      */
    3001     rc = CFGMR3QueryBoolDef(pCfgNem, "CatalinaWxWorkaround", &g_fAppleHvNoWX, false);
    30022894    AssertRCReturn(rc, rc);
    30032895
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