Changeset 75049 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Oct 24, 2018 4:06:42 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 126096
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r75003 r75049 5557 5557 5558 5558 /** 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 */ 5565 int 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 /** 5559 5579 * Updates the VMMR0 entry point pointers. 5560 5580 * -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r75003 r75049 368 368 /** Hack for seeing the module in perf, dtrace and other stack crawlers. */ 369 369 struct module *pLnxModHack; 370 #endif 371 #if defined(RT_OS_DARWIN) 372 /** Load module handle. */ 373 RTLDRMOD hLdrMod; 374 /** Allocate object. */ 375 RTR0MEMOBJ hMemAlloc; 370 376 #endif 371 377 /** Whether it's loaded by the native loader or not. */ … … 1027 1033 int VBOXCALL supdrvQueryVTCapsInternal(uint32_t *pfCaps); 1028 1034 int VBOXCALL supdrvLdrLoadError(int rc, PSUPLDRLOAD pReq, const char *pszFormat, ...); 1035 int VBOXCALL supdrvLdrGetExportedSymbol(const char *pszSymbol, uintptr_t *puValue); 1029 1036 1030 1037 /* SUPDrvGip.cpp */ -
trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
r75003 r75049 1143 1143 1144 1144 1145 #ifdef SUPDRV_WITH_DARWIN_IMAGE_VERIFICATION 1146 1147 /** 1148 * @callback_method_impl{FNRTLDRIMPORT} 1149 */ 1150 static 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 */ 1190 static 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 */ 1250 static 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 1145 1283 int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename) 1146 1284 { 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 */ 1147 1371 NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename); 1148 1372 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 */ 1382 static 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 1150 1391 1151 1392 … … 1153 1394 const uint8_t *pbImageBits, const char *pszSymbol) 1154 1395 { 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 1155 1441 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol); 1156 1442 return VERR_NOT_SUPPORTED; 1443 #endif 1157 1444 } 1158 1445 … … 1160 1447 int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq) 1161 1448 { 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 1162 1464 NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq); 1163 1465 return VERR_NOT_SUPPORTED; 1466 #endif 1164 1467 } 1165 1468 … … 1167 1470 void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage) 1168 1471 { 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 1169 1486 NOREF(pDevExt); NOREF(pImage); 1487 #endif 1170 1488 } 1171 1489 -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r75003 r75049 2207 2207 } 2208 2208 } 2209 SUPR0Printf("SUPDrv: No export named %s (%#x) in 2209 SUPR0Printf("SUPDrv: No export named %s (%#x) in %s!\n", pszSymbol, uRvaToValidate, pImage->szName); 2210 2210 return VERR_SYMBOL_NOT_FOUND; 2211 2211 }
Note:
See TracChangeset
for help on using the changeset viewer.