VirtualBox

Changeset 75003 in vbox


Ignore:
Timestamp:
Oct 23, 2018 2:24:24 PM (6 years ago)
Author:
vboxsync
Message:

SUPDrv: Adjusted ep validation a little in prep for bugref:9232

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

Legend:

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

    r73389 r75003  
    49824982 *
    49834983 * @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.
    49904993 *
    49914994 * @remarks Will leave the lock on failure.
    49924995 */
    4993 static int supdrvLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv,
    4994                                     bool fMayBeNull, const uint8_t *pbImageBits, const char *pszWhat)
     4996static int supdrvLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, bool fMayBeNull,
     4997                                    bool fCheckNative, const uint8_t *pbImageBits, const char *pszSymbol)
    49954998{
    49964999    if (!fMayBeNull || pv)
     
    49995002        {
    50005003            supdrvLdrUnlock(pDevExt);
    5001             Log(("Out of range (%p LB %#x): %s=%p\n", pImage->pvImage, pImage->cbImageBits, pszWhat, pv));
     5004            Log(("Out of range (%p LB %#x): %s=%p\n", pImage->pvImage, pImage->cbImageBits, pszSymbol, pv));
    50025005            return VERR_INVALID_PARAMETER;
    50035006        }
    50045007
    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);
    50085011            if (RT_FAILURE(rc))
    50095012            {
    50105013                supdrvLdrUnlock(pDevExt);
    5011                 Log(("Bad entry point address: %s=%p (rc=%Rrc)\n", pszWhat, pv, rc)); NOREF(pszWhat);
     5014                Log(("Bad entry point address: %s=%p (rc=%Rrc)\n", pszSymbol, pv, rc));
    50125015                return rc;
    50135016            }
     
    51085111
    51095112        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");
    51115114            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");
    51135116            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");
    51155118            if (RT_FAILURE(rc))
    51165119                return supdrvLdrLoadError(rc, pReq, "Invalid VMMR0 pointer");
     
    51185121
    51195122        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");
    51215124            if (RT_FAILURE(rc))
    51225125                return supdrvLdrLoadError(rc, pReq, "Invalid pfnServiceReq pointer: %p", pReq->u.In.EP.Service.pfnServiceReq);
     
    51405143    }
    51415144
    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");
    51435146    if (RT_FAILURE(rc))
    51445147        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");
    51465149    if (RT_FAILURE(rc))
    51475150        return supdrvLdrLoadError(rc, pReq, "Invalid pfnModuleTerm pointer: %p", pReq->u.In.pfnModuleTerm);
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r71198 r75003  
    917917 * @param   pv                  The address within the image.
    918918 * @param   pbImageBits         The image bits as loaded by ring-3.
     919 * @param   pszSymbol           The name of the entrypoint being checked.
    919920 */
    920921int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage,
    921                                            void *pv, const uint8_t *pbImageBits);
     922                                           void *pv, const uint8_t *pbImageBits, const char *pszSymbol);
    922923
    923924/**
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp

    r71198 r75003  
    11501150
    11511151
    1152 int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
    1153 {
    1154     NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
     1152int  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);
    11551156    return VERR_NOT_SUPPORTED;
    11561157}
  • trunk/src/VBox/HostDrivers/Support/freebsd/SUPDrv-freebsd.c

    r71198 r75003  
    559559
    560560
    561 int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
    562 {
    563     NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
     561int  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);
    564565    return VERR_NOT_SUPPORTED;
    565566}
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r73542 r75003  
    846846
    847847
    848 int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
    849 {
    850     NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
     848int  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);
    851852    return VERR_NOT_SUPPORTED;
    852853}
  • trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp

    r71198 r75003  
    432432
    433433
    434 int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
    435 {
    436     NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
     434int  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);
    437438    return VERR_NOT_SUPPORTED;
    438439}
  • trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c

    r71198 r75003  
    10611061
    10621062
    1063 int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
    1064 {
    1065     NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
     1063int  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);
    10661067    if (kobj_addrcheck(pImage->pSolModCtl->mod_mp, pv))
    10671068        return VERR_INVALID_PARAMETER;
     
    12051206
    12061207
    1207 int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv, const uint8_t *pbImageBits)
    1208 {
    1209     NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits);
     1208int  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);
    12101212    return VERR_NOT_SUPPORTED;
    12111213}
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r73097 r75003  
    20082008                 Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer));
    20092009# 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",
    20112011                        Info.ImageAddress, Info.SectionPointer, Info.ImageLength, pImage->cbImageBits, rcNt, Info.Name.Buffer);
    20122012# endif
     
    20882088}
    20892089
    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 */
     2093int  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    }
    20932212    return VINF_SUCCESS;
     2213
     2214#else
     2215    NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol);
     2216    return VERR_NOT_SUPPORTED;
     2217#endif
    20942218}
    20952219
     
    21792303        /*
    21802304         * 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.
    21832306         */
    21842307        uint32_t const  offNtHdrs = *(uint16_t *)pbImageBits == IMAGE_DOS_SIGNATURE
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