VirtualBox

Changeset 75049 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Oct 24, 2018 4:06:42 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126096
Message:

IPRT,SUPDrv: Added cbImage parameter to FNRTLDRRDRMEMDTOR; sketched the basics for darwin module verification. bugref:9232

Location:
trunk/src/VBox/HostDrivers/Support
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp

    r75003 r75049  
    55575557
    55585558/**
     5559 * Looks up a symbol in g_aFunctions
     5560 *
     5561 * @returns VINF_SUCCESS on success, VERR_SYMBOL_NOT_FOUND on failure.
     5562 * @param   pszSymbol   The symbol to look up.
     5563 * @param   puValue     Where to return the value.
     5564 */
     5565int VBOXCALL supdrvLdrGetExportedSymbol(const char *pszSymbol, uintptr_t *puValue)
     5566{
     5567    uint32_t i;
     5568    for (i = 0; i < RT_ELEMENTS(g_aFunctions); i++)
     5569        if (!strcmp(g_aFunctions[i].szName, pszSymbol))
     5570        {
     5571            *puValue = (uintptr_t)g_aFunctions[i].pfn;
     5572            return VINF_SUCCESS;
     5573        }
     5574    return VERR_SYMBOL_NOT_FOUND;
     5575}
     5576
     5577
     5578/**
    55595579 * Updates the VMMR0 entry point pointers.
    55605580 *
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r75003 r75049  
    368368    /** Hack for seeing the module in perf, dtrace and other stack crawlers. */
    369369    struct module                  *pLnxModHack;
     370#endif
     371#if defined(RT_OS_DARWIN)
     372    /** Load module handle. */
     373    RTLDRMOD                        hLdrMod;
     374    /** Allocate object. */
     375    RTR0MEMOBJ                      hMemAlloc;
    370376#endif
    371377    /** Whether it's loaded by the native loader or not. */
     
    10271033int VBOXCALL    supdrvQueryVTCapsInternal(uint32_t *pfCaps);
    10281034int VBOXCALL    supdrvLdrLoadError(int rc, PSUPLDRLOAD pReq, const char *pszFormat, ...);
     1035int VBOXCALL    supdrvLdrGetExportedSymbol(const char *pszSymbol, uintptr_t *puValue);
    10291036
    10301037/* SUPDrvGip.cpp */
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp

    r75003 r75049  
    11431143
    11441144
     1145#ifdef SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION
     1146
     1147/**
     1148 * @callback_method_impl{FNRTLDRIMPORT}
     1149 */
     1150static DECLCALLBACK(int) supdrvDarwinLdrOpenImportCallback(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol,
     1151                                                           unsigned uSymbol, PRTLDRADDR pValue, void *pvUser)
     1152{
     1153    PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
     1154
     1155    /*
     1156     * Consult the SUPDrv export table first.
     1157     */
     1158    uintptr_t uValue = 0;
     1159    int rc = supdrvLdrGetExportedSymbol(pszSymbol, &uValue);
     1160    if (RT_SUCCESS(rc))
     1161    {
     1162        *pValue = uValue;
     1163        return VINF_SUCCESS;
     1164    }
     1165
     1166    /*
     1167     * Check already loaded modules.
     1168     */
     1169    for (PSUPDRVLDRIMAGE pImage = pDevExt->pLdrImages; pImage; pImage = pImage->pNext);
     1170        if (   pImage->uState == SUP_IOCTL_LDR_LOAD
     1171            && pImage->hLdrMod != NIL_RTLDRMOD)
     1172        {
     1173            rc = RTLdrGetSymbolEx(pImage->hLdrMod, pImage->pvImage, (uintptr_t)pImage->pvImage, UINT32_MAX, pszSymbol, pValue);
     1174            if (RT_SUCCESS(rc))
     1175                return VINF_SUCCESS;
     1176        }
     1177
     1178    /*
     1179     * Failed.
     1180     */
     1181    printf("VBoxDrv: Unable to resolve symbol '%s'.\n", pszSymbol);
     1182    return VERR_SYMBOL_NOT_FOUND;
     1183}
     1184
     1185
     1186/**
     1187 * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK,
     1188 *      Verify that the signing certificate is sane.}
     1189 */
     1190static DECLCALLBACK(int) supdrvDarwinLdrOpenVerifyCertificatCallback(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths,
     1191                                                                     uint32_t fFlags, void *pvUser, PRTERRINFO pErrInfo)
     1192{
     1193    RT_NOREF(pvUser); //PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
     1194
     1195# if 0
     1196    /*
     1197     * Test signing certificates normally doesn't have all the necessary
     1198     * features required below.  So, treat them as special cases.
     1199     */
     1200    if (   hCertPaths == NIL_RTCRX509CERTPATHS
     1201        && RTCrX509Name_Compare(&pCert->TbsCertificate.Issuer, &pCert->TbsCertificate.Subject) == 0)
     1202    {
     1203        RTMsgInfo("Test signed.\n");
     1204        return VINF_SUCCESS;
     1205    }
     1206# endif
     1207
     1208    /*
     1209     * Standard code signing capabilites required.
     1210     */
     1211    int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, fFlags, NULL, pErrInfo);
     1212    if (   RT_SUCCESS(rc)
     1213        && (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA))
     1214    {
     1215        uint32_t cDevIdApp  = 0;
     1216        uint32_t cDevIdKext = 0;
     1217        for (uint32_t i = 0; i < pCert->TbsCertificate.T3.Extensions.cItems; i++)
     1218        {
     1219            PCRTCRX509EXTENSION pExt = pCert->TbsCertificate.T3.Extensions.papItems[i];
     1220            if (RTAsn1ObjId_CompareWithString(&pExt->ExtnId, RTCR_APPLE_CS_DEVID_APPLICATION_OID) == 0)
     1221            {
     1222                cDevIdApp++;
     1223                if (!pExt->Critical.fValue)
     1224                    rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     1225                                       "Dev ID Application certificate extension is not flagged critical");
     1226            }
     1227            else if (RTAsn1ObjId_CompareWithString(&pExt->ExtnId, RTCR_APPLE_CS_DEVID_KEXT_OID) == 0)
     1228            {
     1229                cDevIdKext++;
     1230                if (!pExt->Critical.fValue)
     1231                    rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     1232                                       "Dev ID kext certificate extension is not flagged critical");
     1233            }
     1234        }
     1235        if (cDevIdApp == 0)
     1236            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     1237                               "Certificate is missing the 'Dev ID Application' extension");
     1238        if (cDevIdKext == 0 && pState->fKernel)
     1239            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
     1240                               "Certificate is missing the 'Dev ID kext' extension");
     1241    }
     1242
     1243    return rc;
     1244}
     1245
     1246
     1247/**
     1248 * @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}
     1249 */
     1250static DECLCALLBACK(int) supdrvDarwinLdrOpenVerifyCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
     1251                                                           void const *pvSignature, size_t cbSignature,
     1252                                                           void const *pvExternalData, size_t cbExternalData,
     1253                                                           PRTERRINFO pErrInfo, void *pvUser)
     1254{
     1255    PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
     1256    switch (enmSignature)
     1257    {
     1258        case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
     1259            if (pvExternalData)
     1260            {
     1261                PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
     1262                RTTIMESPEC             ValidationTime;
     1263                RTTimeNow(&ValidationTime)
     1264
     1265                return RTCrPkcs7VerifySignedDataWithExternalData(pContentInfo,
     1266                                                                 RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
     1267                                                                 | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
     1268                                                                 | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT,
     1269                                                                 pDevExt->hAdditionalStore, pDevExt->hRootStore, &ValidationTime,
     1270                                                                 supdrvDarwinLdrOpenVerifyCertificatCallback, pDevExt
     1271                                                                 pvExternalData, cbExternalData, pErrInfo);
     1272            }
     1273            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Expected external data with signature!");
     1274
     1275        default:
     1276            RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
     1277            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
     1278    }
     1279}
     1280
     1281#endif /* SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION */
     1282
    11451283int  VBOXCALL   supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
    11461284{
     1285#ifdef SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION
     1286    /*
     1287     * Initialize our members.
     1288     */
     1289    pImage->hLdrMod   = NIL_RTLDRMOD;
     1290    pImage->hMemAlloc = NIL_RTR0MEMOBJ;
     1291
     1292    /*
     1293     * We have to double buffer the file to be avoid a potential race between
     1294     * validation and actual image loading.  This could be eliminated later by
     1295     * baking the image validation into the RTLdrGetBits operation.
     1296     *
     1297     * Note! After calling RTLdrOpenInMemory, pvFile is owned by the loader and will be
     1298     *       freed via the RTFileReadAllFree callback when the loader module is closed.
     1299     */
     1300    void     *pvFile  = NULL;
     1301    size_t   *pcbFile = 0;
     1302    int rc = RTFileReadAllEx(pszFilename, 0, _32M, RTFILE_RDALL_O_DENY_WRITE, &pvFile, &cbFile);
     1303    if (RT_SUCCESS(rc))
     1304    {
     1305        PRTERRINFOSTATIC pErrInfo = (PRTERRINFOSTATIC)RTMemTmpAlloc(sizeof(RTERRINFOSTATIC));
     1306        RTLDRMOD         hLdrMod = NIL_RTLDRMOD;
     1307        rc = RTLdrOpenInMemory(pszFilename, 0 /*fFlags*/, RTLDRARCH_HOST, cbFile,
     1308                               NULL /*pfnRead*/, RTFileReadAllFree, pvFile,
     1309                               &hLdrMod, pErrInfo ? RTErrInfoInitStatic(pErrInfo) : NULL);
     1310        if (RT_SUCCESS(rc))
     1311        {
     1312            /*
     1313             * Validate the image.
     1314             */
     1315            rc = RTLdrVerifySignature(hLdrMod, supdrvDarwinLdrOpenVerifyCallback, pDevExt,
     1316                                      pErrInfo ? RTErrInfoInitStatic(pErrInfo) : NULL);
     1317            if (RT_SUCCESS(rc))
     1318            {
     1319                /*
     1320                 * Allocate memory for the object and load it into it.
     1321                 */
     1322                size_t cbImage = RTLdrSize(hLdrMod);
     1323                if (cbImage == pImage->cbImageBits)
     1324                {
     1325                    RTR0MEMOBJ hMemAlloc;
     1326                    rc = RTR0MemObjAllocPage(&hMemAlloc, cbImage, true /*fExecutable*/);
     1327                    if (RT_SUCCESS(rc))
     1328                    {
     1329                        void *pvImageBits = RTR0MemObjAddress(hMemAlloc);
     1330                        rc = RTLdrGetBits(hLdrMod, pvImageBits, (uintptr_t)pvImageBits,
     1331                                          supdrvDarwinLdrOpenImportCallback, pDevExt);
     1332                        if (RT_SUCCESS(rc))
     1333                        {
     1334                            /*
     1335                             * Commit.
     1336                             */
     1337                            pImage->hMemAlloc   = hMemAlloc;
     1338                            pImage->hLdrMod     = hLdrMod;
     1339                            pImage->pvImage     = pvImageBits;
     1340                            RTMemTmpFree(pErrInfo);
     1341                            /** @todo Call RTLdrDone. */
     1342                            return VINF_SUCCESS;
     1343                        }
     1344
     1345                        RTR0MemObjFree(hMemObj, true /*fFreeMappings*/);
     1346                    }
     1347                    else
     1348                        printf("VBoxDrv: Failed to allocate %u bytes for %s: %d\n", (unsigned)cbImage, rc);
     1349                }
     1350                else
     1351                {
     1352                    printf("VBoxDrv: Image size mismatch for %s: %#x, ring-3 says %#x\n",
     1353                           pszFilename, cbImage, pImage->cbImageBits);
     1354                    rc = VERR_LDR_MISMATCH_NATIVE;
     1355                }
     1356            }
     1357            else if (pErrInfo && RTErrInfoIsSet(&pErrInfo->Core))
     1358                printf("VBoxDrv: RTLdrOpenInMemory(%s) failed: %d - %s\n", pszFilename, rc, pErrInfo->Core.pszMsg);
     1359            else
     1360                printf("VBoxDrv: RTLdrOpenInMemory(%s) failed: %d\n", pszFilename, rc);
     1361            RTLdrClose(hLdrMod);
     1362        }
     1363        else if (pErrInfo && RTErrInfoIsSet(&pErrInfo->Core))
     1364            printf("VBoxDrv: RTLdrOpenInMemory(%s) failed: %d - %s\n", pszFilename, rc, pErrInfo->Core.pszMsg);
     1365        else
     1366            printf("VBoxDrv: RTLdrOpenInMemory(%s) failed: %d\n", pszFilename, rc);
     1367        RTMemTmpFree(pErrInfo);
     1368    }
     1369    return rc;
     1370#else  /* !SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION */
    11471371    NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
    11481372    return VERR_NOT_SUPPORTED;
    1149 }
     1373#endif /* !SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION */
     1374}
     1375
     1376
     1377#ifdef SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION
     1378/**
     1379 *  @callback_method_impl{FNRTLDRENUMSYMS,
     1380 *      Worker for supdrvOSLdrValidatePointer.
     1381 */
     1382static DECLCALLBACK(int) supdrvDarwinLdrValidatePointerCallback(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol,
     1383                                                                RTLDRADDR Value, void *pvUser)
     1384{
     1385    RT_NOREF(hLdrMod, pszSymbol, uSymbol);
     1386    if (uValue == (uintptr_t)pvUser)
     1387        return VINF_CALLBACK_RETURN;
     1388    return VINF_SUCCESS;
     1389}
     1390#endif
    11501391
    11511392
     
    11531394                                           const uint8_t *pbImageBits, const char *pszSymbol)
    11541395{
     1396#ifdef SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION
     1397    AssertReturn(pImage->hLdrMod != NIL_RTLDRMOD, VERR_INVALID_STATE);
     1398
     1399    /*
     1400     * If we've got a symbol name, just to a lookup and compare addresses.
     1401     */
     1402    int rc;
     1403    if (RT_C_IS_UPPER(*pszSymbol))
     1404    {
     1405        void *pvFound = NULL;
     1406        rc = RTLdrGetSymbol(pImage->hLdrMod, pszSymbol, &pvFound);
     1407        if (RT_SUCCESS(rc))
     1408        {
     1409            if (pvFound == pv)
     1410                rc = VINF_SUCCESS;
     1411            else
     1412            {
     1413                SUPR0Printf("SUPDrv: Different exports found for %s in %s: %p, expected %p\n",
     1414                            pszSymbol, pImage->szName, pvFound, pv);
     1415                rc = VERR_LDR_BAD_FIXUP;
     1416            }
     1417        }
     1418        else
     1419            SUPR0Printf("SUPDrv: No export named %s (%p) in %s!\n", pszSymbol, uRvaToValidate, pImage->szName);
     1420    }
     1421    /*
     1422     * Otherwise do a symbol enumeration and look for the entrypoint.
     1423     */
     1424    else
     1425    {
     1426        rc = RTLdrEnumSymbols(pImage->hLdrMod, 0 /*fFlags*/, pImage->pvImage, (uintptr_t)pImage->pvImage,
     1427                              supdrvDarwinLdrValidatePointerCallback, pv);
     1428        if (rc == VINF_CALLBACK_RETURN)
     1429            rc = VINF_SUCCESS;
     1430        else if (RT_SUCCESS(rc))
     1431        {
     1432            SUPR0Printf("SUPDrv: No export with address %p (%s) in %s!\n", pv, pszSymbol, pImage->szName);
     1433            rc = VERR_NOT_FOUND;
     1434        }
     1435        else
     1436            SUPR0Printf("SUPDrv: RTLdrEnumSymbols failed on %s: %Rrc\n", pImage->szName, rc);
     1437    }
     1438    RT_NOREF(pDevExt, pbImageBits);
     1439    return rc;
     1440#else
    11551441    NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol);
    11561442    return VERR_NOT_SUPPORTED;
     1443#endif
    11571444}
    11581445
     
    11601447int  VBOXCALL   supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
    11611448{
     1449#ifdef SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION
     1450    /* State paranoia. */
     1451    AssertReturn(pImage->hLdrMod != NIL_RTLDRMOD, VERR_INVALID_STATE);
     1452    AssertReturn(pImage->hMemAlloc != NIL_RTR0MEMOBJ, VERR_INVALID_STATE);
     1453    AssertReturn(pImage->pvImage, VERR_INVALID_STATE);
     1454
     1455    /*
     1456     * We should get an identical match with ring-3 here, so the code here is
     1457     * trivial in comparision to SUPDrv-win.cpp.
     1458     */
     1459    if (!memcmp(pImage->pvImage, pbImageBits, pImage->cbImageBits))
     1460        return VINF_SUCCESS;
     1461    return VERR_LDR_MISMATCH_NATIVE;
     1462
     1463#else
    11621464    NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
    11631465    return VERR_NOT_SUPPORTED;
     1466#endif
    11641467}
    11651468
     
    11671470void VBOXCALL   supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
    11681471{
     1472#ifdef
     1473    if (pImage->hLdrMod != NIL_RTLDRMOD)
     1474    {
     1475        int rc = RTLdrClose(pImage->hLdrMod);
     1476        AssertRC(rc);
     1477        pImage->hLdrMod = NIL_RTLDRMOD;
     1478    }
     1479    if (pImage->hMemAlloc != NIL_RTR0MEMOBJ)
     1480    {
     1481        RTR0MemObjFree(pImage->hMemAlloc, true /*fFreeMappings*/);
     1482        pImage->hMemAlloc = NIL_RTR0MEMOBJ;
     1483    }
     1484    NOREF(pDevExt);
     1485#else
    11691486    NOREF(pDevExt); NOREF(pImage);
     1487#endif
    11701488}
    11711489
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r75003 r75049  
    22072207            }
    22082208        }
    2209         SUPR0Printf("SUPDrv: No export named %s (%#x) in  %s!\n", pszSymbol, uRvaToValidate, pImage->szName);
     2209        SUPR0Printf("SUPDrv: No export named %s (%#x) in %s!\n", pszSymbol, uRvaToValidate, pImage->szName);
    22102210        return VERR_SYMBOL_NOT_FOUND;
    22112211    }
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette