Changeset 75003 in vbox
- Timestamp:
- Oct 23, 2018 2:24:24 PM (6 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r73389 r75003 4982 4982 * 4983 4983 * @returns IPRT status code. 4984 * @param pDevExt The device globals. 4985 * @param pImage The loader image. 4986 * @param pv The pointer into the image. 4987 * @param fMayBeNull Whether it may be NULL. 4988 * @param pszWhat What is this entrypoint? (for logging) 4989 * @param pbImageBits The image bits prepared by ring-3. 4984 * @param pDevExt The device globals. 4985 * @param pImage The loader image. 4986 * @param pv The pointer into the image. 4987 * @param fMayBeNull Whether it may be NULL. 4988 * @param fCheckNative Whether to check with the native loaders. 4989 * @param pszSymbol The entrypoint name or log name. If the symbol 4990 * capitalized it signifies a specific symbol, otherwise it 4991 * for logging. 4992 * @param pbImageBits The image bits prepared by ring-3. 4990 4993 * 4991 4994 * @remarks Will leave the lock on failure. 4992 4995 */ 4993 static int supdrvLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, 4994 bool f MayBeNull, const uint8_t *pbImageBits, const char *pszWhat)4996 static int supdrvLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, bool fMayBeNull, 4997 bool fCheckNative, const uint8_t *pbImageBits, const char *pszSymbol) 4995 4998 { 4996 4999 if (!fMayBeNull || pv) … … 4999 5002 { 5000 5003 supdrvLdrUnlock(pDevExt); 5001 Log(("Out of range (%p LB %#x): %s=%p\n", pImage->pvImage, pImage->cbImageBits, psz What, pv));5004 Log(("Out of range (%p LB %#x): %s=%p\n", pImage->pvImage, pImage->cbImageBits, pszSymbol, pv)); 5002 5005 return VERR_INVALID_PARAMETER; 5003 5006 } 5004 5007 5005 if (pImage->fNative )5006 { 5007 int rc = supdrvOSLdrValidatePointer(pDevExt, pImage, pv, pbImageBits );5008 if (pImage->fNative && fCheckNative) 5009 { 5010 int rc = supdrvOSLdrValidatePointer(pDevExt, pImage, pv, pbImageBits, pszSymbol); 5008 5011 if (RT_FAILURE(rc)) 5009 5012 { 5010 5013 supdrvLdrUnlock(pDevExt); 5011 Log(("Bad entry point address: %s=%p (rc=%Rrc)\n", psz What, pv, rc)); NOREF(pszWhat);5014 Log(("Bad entry point address: %s=%p (rc=%Rrc)\n", pszSymbol, pv, rc)); 5012 5015 return rc; 5013 5016 } … … 5108 5111 5109 5112 case SUPLDRLOADEP_VMMR0: 5110 rc = supdrvLdrValidatePointer( pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0, false, pReq->u.In.abImage, "pvVMMR0");5113 rc = supdrvLdrValidatePointer( pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0, false, false, pReq->u.In.abImage, "pvVMMR0"); 5111 5114 if (RT_SUCCESS(rc)) 5112 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0EntryFast, false, pReq->u.In.abImage, "pvVMMR0EntryFast");5115 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0EntryFast, false, true, pReq->u.In.abImage, "VMMR0EntryFast"); 5113 5116 if (RT_SUCCESS(rc)) 5114 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0EntryEx, false, pReq->u.In.abImage, "pvVMMR0EntryEx");5117 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.VMMR0.pvVMMR0EntryEx, false, true, pReq->u.In.abImage, "VMMR0EntryEx"); 5115 5118 if (RT_FAILURE(rc)) 5116 5119 return supdrvLdrLoadError(rc, pReq, "Invalid VMMR0 pointer"); … … 5118 5121 5119 5122 case SUPLDRLOADEP_SERVICE: 5120 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.Service.pfnServiceReq, false, pReq->u.In.abImage, "pfnServiceReq");5123 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.EP.Service.pfnServiceReq, false, true, pReq->u.In.abImage, "pfnServiceReq"); 5121 5124 if (RT_FAILURE(rc)) 5122 5125 return supdrvLdrLoadError(rc, pReq, "Invalid pfnServiceReq pointer: %p", pReq->u.In.EP.Service.pfnServiceReq); … … 5140 5143 } 5141 5144 5142 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.pfnModuleInit, true, pReq->u.In.abImage, "pfnModuleInit");5145 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.pfnModuleInit, true, true, pReq->u.In.abImage, "ModuleInit"); 5143 5146 if (RT_FAILURE(rc)) 5144 5147 return supdrvLdrLoadError(rc, pReq, "Invalid pfnModuleInit pointer: %p", pReq->u.In.pfnModuleInit); 5145 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.pfnModuleTerm, true, pReq->u.In.abImage, "pfnModuleTerm");5148 rc = supdrvLdrValidatePointer(pDevExt, pImage, pReq->u.In.pfnModuleTerm, true, true, pReq->u.In.abImage, "ModuleTerm"); 5146 5149 if (RT_FAILURE(rc)) 5147 5150 return supdrvLdrLoadError(rc, pReq, "Invalid pfnModuleTerm pointer: %p", pReq->u.In.pfnModuleTerm); -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r71198 r75003 917 917 * @param pv The address within the image. 918 918 * @param pbImageBits The image bits as loaded by ring-3. 919 * @param pszSymbol The name of the entrypoint being checked. 919 920 */ 920 921 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, 921 void *pv, const uint8_t *pbImageBits );922 void *pv, const uint8_t *pbImageBits, const char *pszSymbol); 922 923 923 924 /** -
trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
r71198 r75003 1150 1150 1151 1151 1152 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits) 1153 { 1154 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); 1152 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, 1153 const uint8_t *pbImageBits, const char *pszSymbol) 1154 { 1155 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol); 1155 1156 return VERR_NOT_SUPPORTED; 1156 1157 } -
trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c
r71198 r75003 559 559 560 560 561 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits) 562 { 563 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); 561 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, 562 const uint8_t *pbImageBits, const char *pszSymbol) 563 { 564 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol); 564 565 return VERR_NOT_SUPPORTED; 565 566 } -
trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
r73542 r75003 846 846 847 847 848 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits) 849 { 850 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); 848 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, 849 const uint8_t *pbImageBits, const char *pszSymbol) 850 { 851 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol); 851 852 return VERR_NOT_SUPPORTED; 852 853 } -
trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp
r71198 r75003 432 432 433 433 434 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits) 435 { 436 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); 434 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, 435 const uint8_t *pbImageBits, const char *pszSymbol) 436 { 437 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol); 437 438 return VERR_NOT_SUPPORTED; 438 439 } -
trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
r71198 r75003 1061 1061 1062 1062 1063 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits) 1064 { 1065 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); 1063 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, 1064 const uint8_t *pbImageBits, const char *pszSymbol) 1065 { 1066 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol); 1066 1067 if (kobj_addrcheck(pImage->pSolModCtl->mod_mp, pv)) 1067 1068 return VERR_INVALID_PARAMETER; … … 1205 1206 1206 1207 1207 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits) 1208 { 1209 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); 1208 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, 1209 const uint8_t *pbImageBits, const char *pszSymbol) 1210 { 1211 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol); 1210 1212 return VERR_NOT_SUPPORTED; 1211 1213 } -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r73097 r75003 2008 2008 Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer)); 2009 2009 # ifdef DEBUG_bird 2010 SUPR0Printf("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '% ws'\n",2010 SUPR0Printf("ImageAddress=%p SectionPointer=%p ImageLength=%#x cbImageBits=%#x rcNt=%#x '%ls'\n", 2011 2011 Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer); 2012 2012 # endif … … 2088 2088 } 2089 2089 2090 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits) 2091 { 2092 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); 2090 /* 2091 * Note! Similar code in rtR0DbgKrnlNtParseModule. 2092 */ 2093 int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, 2094 const uint8_t *pbImageBits, const char *pszSymbol) 2095 { 2096 #if 1 2097 RT_NOREF(pDevExt, pbImageBits); 2098 AssertReturn(pImage->pvNtSectionObj, VERR_INVALID_STATE); 2099 2100 /* 2101 * Locate the export directory in the loaded image. 2102 */ 2103 uint8_t const *pbMapping = (uint8_t const *)pImage->pvImage; 2104 uint32_t const cbMapping = pImage->cbImageBits; 2105 uint32_t const uRvaToValidate = (uint32_t)((uintptr_t)pv - (uintptr_t)pbMapping); 2106 AssertReturn(uRvaToValidate < cbMapping, VERR_INTERNAL_ERROR_3); 2107 2108 uint32_t const offNtHdrs = *(uint16_t *)pbMapping == IMAGE_DOS_SIGNATURE 2109 ? ((IMAGE_DOS_HEADER const *)pbMapping)->e_lfanew 2110 : 0; 2111 AssertLogRelReturn(offNtHdrs + sizeof(IMAGE_NT_HEADERS) < cbMapping, VERR_INTERNAL_ERROR_5); 2112 2113 IMAGE_NT_HEADERS const *pNtHdrs = (IMAGE_NT_HEADERS const *)((uintptr_t)pbMapping + offNtHdrs); 2114 AssertLogRelReturn(pNtHdrs->Signature == IMAGE_NT_SIGNATURE, VERR_INVALID_EXE_SIGNATURE); 2115 AssertLogRelReturn(pNtHdrs->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR_MAGIC, VERR_BAD_EXE_FORMAT); 2116 AssertLogRelReturn(pNtHdrs->OptionalHeader.NumberOfRvaAndSizes == IMAGE_NUMBEROF_DIRECTORY_ENTRIES, VERR_BAD_EXE_FORMAT); 2117 2118 uint32_t const offEndSectHdrs = offNtHdrs 2119 + sizeof(*pNtHdrs) 2120 + pNtHdrs->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER); 2121 AssertReturn(offEndSectHdrs < cbMapping, VERR_BAD_EXE_FORMAT); 2122 2123 /* 2124 * Find the export directory. 2125 */ 2126 IMAGE_DATA_DIRECTORY ExpDir = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 2127 if (!ExpDir.Size) 2128 { 2129 SUPR0Printf("SUPDrv: No exports in %s!\n", pImage->szName); 2130 return VERR_NOT_FOUND; 2131 } 2132 AssertReturn( ExpDir.Size >= sizeof(IMAGE_EXPORT_DIRECTORY) 2133 && ExpDir.VirtualAddress >= offEndSectHdrs 2134 && ExpDir.VirtualAddress < cbMapping 2135 && ExpDir.VirtualAddress + ExpDir.Size <= cbMapping, VERR_BAD_EXE_FORMAT); 2136 2137 IMAGE_EXPORT_DIRECTORY const *pExpDir = (IMAGE_EXPORT_DIRECTORY const *)&pbMapping[ExpDir.VirtualAddress]; 2138 2139 uint32_t const cNamedExports = pExpDir->NumberOfNames; 2140 AssertReturn(cNamedExports < _1M, VERR_BAD_EXE_FORMAT); 2141 AssertReturn(pExpDir->NumberOfFunctions < _1M, VERR_BAD_EXE_FORMAT); 2142 if (pExpDir->NumberOfFunctions == 0 || cNamedExports == 0) 2143 { 2144 SUPR0Printf("SUPDrv: No exports in %s!\n", pImage->szName); 2145 return VERR_NOT_FOUND; 2146 } 2147 2148 uint32_t const cExports = RT_MAX(cNamedExports, pExpDir->NumberOfFunctions); 2149 2150 AssertReturn( pExpDir->AddressOfFunctions >= offEndSectHdrs 2151 && pExpDir->AddressOfFunctions < cbMapping 2152 && pExpDir->AddressOfFunctions + cExports * sizeof(uint32_t) <= cbMapping, 2153 VERR_BAD_EXE_FORMAT); 2154 uint32_t const * const paoffExports = (uint32_t const *)&pbMapping[pExpDir->AddressOfFunctions]; 2155 2156 AssertReturn( pExpDir->AddressOfNames >= offEndSectHdrs 2157 && pExpDir->AddressOfNames < cbMapping 2158 && pExpDir->AddressOfNames + cNamedExports * sizeof(uint32_t) <= cbMapping, 2159 VERR_BAD_EXE_FORMAT); 2160 uint32_t const * const paoffNamedExports = (uint32_t const *)&pbMapping[pExpDir->AddressOfNames]; 2161 2162 AssertReturn( pExpDir->AddressOfNameOrdinals >= offEndSectHdrs 2163 && pExpDir->AddressOfNameOrdinals < cbMapping 2164 && pExpDir->AddressOfNameOrdinals + cNamedExports * sizeof(uint32_t) <= cbMapping, 2165 VERR_BAD_EXE_FORMAT); 2166 uint16_t const * const pau16NameOrdinals = (uint16_t const *)&pbMapping[pExpDir->AddressOfNameOrdinals]; 2167 2168 /* 2169 * Validate the entrypoint RVA by scanning the export table. 2170 */ 2171 uint32_t iExportOrdinal = UINT32_MAX; 2172 for (uint32_t i = 0; i < cExports; i++) 2173 if (paoffExports[i] == uRvaToValidate) 2174 { 2175 iExportOrdinal = i; 2176 break; 2177 } 2178 if (iExportOrdinal == UINT32_MAX) 2179 { 2180 SUPR0Printf("SUPDrv: No export with rva %#x (%s) in %s!\n", uRvaToValidate, pszSymbol, pImage->szName); 2181 return VERR_NOT_FOUND; 2182 } 2183 2184 /* 2185 * Can we validate the symbol name too? If so, just do a linear search. 2186 */ 2187 if (pszSymbol && RT_C_IS_UPPER(*pszSymbol)) 2188 { 2189 size_t const cchSymbol = strlen(pszSymbol); 2190 for (uint32_t i = 0; i < cNamedExports; i++) 2191 { 2192 uint32_t const offName = paoffNamedExports[i]; 2193 AssertReturn(offName < cbMapping, VERR_BAD_EXE_FORMAT); 2194 uint32_t const cchMaxName = cbMapping - offName; 2195 const char * const pszName = (const char *)&pbImageBits[offName]; 2196 const char * const pszEnd = (const char *)memchr(pszName, '\0', cchMaxName); 2197 AssertReturn(pszEnd, VERR_BAD_EXE_FORMAT); 2198 2199 if ( cchSymbol == (size_t)(pszEnd - pszName) 2200 && memcmp(pszName, pszSymbol, cchSymbol) == 0) 2201 { 2202 if (pau16NameOrdinals[i] == iExportOrdinal) 2203 return VINF_SUCCESS; 2204 SUPR0Printf("SUPDrv: Different exports found for %s and rva %#x in %s: %#x vs %#x\n", 2205 pszSymbol, uRvaToValidate, pImage->szName, pau16NameOrdinals[i], iExportOrdinal); 2206 return VERR_LDR_BAD_FIXUP; 2207 } 2208 } 2209 SUPR0Printf("SUPDrv: No export named %s (%#x) in %s!\n", pszSymbol, uRvaToValidate, pImage->szName); 2210 return VERR_SYMBOL_NOT_FOUND; 2211 } 2093 2212 return VINF_SUCCESS; 2213 2214 #else 2215 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol); 2216 return VERR_NOT_SUPPORTED; 2217 #endif 2094 2218 } 2095 2219 … … 2179 2303 /* 2180 2304 * On Windows 10 the ImageBase member of the optional header is sometimes 2181 * updated with the actual load address and sometimes not. Try compare 2182 * 2305 * updated with the actual load address and sometimes not. 2183 2306 */ 2184 2307 uint32_t const offNtHdrs = *(uint16_t *)pbImageBits == IMAGE_DOS_SIGNATURE
Note:
See TracChangeset
for help on using the changeset viewer.