VirtualBox

Ignore:
Timestamp:
Aug 6, 2015 11:34:04 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
101982
Message:

SUPDrv,VMMR0: Added SUPR0BadContext for reporting AC=0 and (on darwin with VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV defined) refuse further I/O control calls. That way we'll sit up and pay attention, hopefully. VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV is currently enabled for all non-release builds (odd build numbers), and we check EFLAGS.AC at the end of each ioctrl call.

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

Legend:

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

    r57220 r57229  
    107107#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX)
    108108# define SUPDRV_CHECK_SMAP_SETUP() uint32_t const fKernelFeatures = SUPR0GetKernelFeatures()
    109 # define SUPDRV_CHECK_SMAP_CHECK(a_BadExpr) \
     109# define SUPDRV_CHECK_SMAP_CHECK(a_pDevExt, a_BadExpr) \
    110110    do { \
    111111        if (fKernelFeatures & SUPKERNELFEATURES_SMAP) \
    112112        { \
    113             RTCCUINTREG uEFlags = ASMGetFlags(); \
    114             if (RT_LIKELY(uEFlags & X86_EFL_AC)) \
     113            RTCCUINTREG fEfl = ASMGetFlags(); \
     114            if (RT_LIKELY(fEfl & X86_EFL_AC)) \
    115115            { /* likely */ } \
    116116            else \
    117117            { \
    118                 SUPR0Printf("%s, line %d: EFLAGS.AC is clear! (%#x)\n", __FUNCTION__, __LINE__, (uint32_t)uEFlags); \
     118                supdrvBadContext(a_pDevExt, "SUPDrv.cpp", __LINE__, "EFLAGS.AC is 0!"); \
    119119                a_BadExpr; \
    120120            } \
     
    122122    } while (0)
    123123#else
    124 # define SUPDRV_CHECK_SMAP_SETUP()          uint32_t const fKernelFeatures = 0
    125 # define SUPDRV_CHECK_SMAP_CHECK(a_BadExpr) NOREF(fKernelFeatures)
     124# define SUPDRV_CHECK_SMAP_SETUP()                      uint32_t const fKernelFeatures = 0
     125# define SUPDRV_CHECK_SMAP_CHECK(a_pDevExt, a_BadExpr) NOREF(fKernelFeatures)
    126126#endif
    127127
     
    189189    { "SUPIsTscFreqCompatible",                 (void *)SUPIsTscFreqCompatible },
    190190    { "SUPIsTscFreqCompatibleEx",               (void *)SUPIsTscFreqCompatibleEx },
     191    { "SUPR0BadContext",                        (void *)SUPR0BadContext },
    191192    { "SUPR0ComponentDeregisterFactory",        (void *)SUPR0ComponentDeregisterFactory },
    192193    { "SUPR0ComponentQueryFactory",             (void *)SUPR0ComponentQueryFactory },
     
    36423643
    36433644/**
     3645 * Reports a bad context, currenctly that means EFLAGS.AC is 0 instead of 1.
     3646 *
     3647 * @param   pSession        The session of the caller.
     3648 * @param   pszFile         The source file where the caller detected the bad
     3649 *                          context.
     3650 * @param   uLine           The line number in @a pszFile.
     3651 * @param   pszExtra        Optional additional message to give further hints.
     3652 */
     3653void VBOXCALL supdrvBadContext(PSUPDRVDEVEXT pDevExt, const char *pszFile, uint32_t uLine, const char *pszExtra)
     3654{
     3655    uint32_t cCalls;
     3656
     3657    /*
     3658     * Shorten the filename before displaying the message.
     3659     */
     3660    for (;;)
     3661    {
     3662        const char *pszTmp = strchr(pszFile, '/');
     3663        if (!pszTmp)
     3664            pszTmp = strchr(pszFile, '\\');
     3665        if (!pszTmp)
     3666            break;
     3667        pszFile = pszTmp + 1;
     3668    }
     3669    if (RT_VALID_PTR(pszExtra) && *pszExtra)
     3670        SUPR0Printf("vboxdrv: Bad CPU context error at line %u in %s: %s\n", uLine, pszFile, pszExtra);
     3671    else
     3672        SUPR0Printf("vboxdrv: Bad CPU context error at line %u in %s!\n", uLine, pszFile);
     3673
     3674    /*
     3675     * Record the incident so that we stand a chance of blocking I/O controls
     3676     * before panicing the system.
     3677     */
     3678    cCalls = ASMAtomicIncU32(&pDevExt->cBadContextCalls);
     3679    if (cCalls > UINT32_MAX - _1K)
     3680        ASMAtomicWriteU32(&pDevExt->cBadContextCalls, UINT32_MAX - _1K);
     3681}
     3682
     3683
     3684/**
     3685 * Reports a bad context, currenctly that means EFLAGS.AC is 0 instead of 1.
     3686 *
     3687 * @param   pSession        The session of the caller.
     3688 * @param   pszFile         The source file where the caller detected the bad
     3689 *                          context.
     3690 * @param   uLine           The line number in @a pszFile.
     3691 * @param   pszExtra        Optional additional message to give further hints.
     3692 */
     3693SUPR0DECL(void) SUPR0BadContext(PSUPDRVSESSION pSession, const char *pszFile, uint32_t uLine, const char *pszExtra)
     3694{
     3695    PSUPDRVDEVEXT pDevExt;
     3696
     3697    AssertReturnVoid(SUP_IS_SESSION_VALID(pSession));
     3698    pDevExt = pSession->pDevExt;
     3699
     3700    supdrvBadContext(pDevExt, pszFile, uLine, pszExtra);
     3701}
     3702
     3703
     3704/**
    36443705 * Gets the paging mode of the current CPU.
    36453706 *
     
    44754536    size_t          cchName = strlen(pReq->u.In.szName); /* (caller checked < 32). */
    44764537    SUPDRV_CHECK_SMAP_SETUP();
    4477     SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4538    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    44784539    LogFlow(("supdrvIOCtl_LdrOpen: szName=%s cbImageWithTabs=%d\n", pReq->u.In.szName, pReq->u.In.cbImageWithTabs));
    44794540
     
    44824543     */
    44834544    supdrvLdrLock(pDevExt);
    4484     SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4545    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    44854546    for (pImage = pDevExt->pLdrImages; pImage; pImage = pImage->pNext)
    44864547    {
     
    44974558                supdrvLdrAddUsage(pSession, pImage);
    44984559                supdrvLdrUnlock(pDevExt);
    4499                 SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4560                SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    45004561                return VINF_SUCCESS;
    45014562            }
     
    45264587        return /*VERR_NO_MEMORY*/ VERR_INTERNAL_ERROR_2;
    45274588    }
    4528     SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4589    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    45294590
    45304591    /*
     
    45604621        pImage->fNative     = false;
    45614622        rc = pImage->pvImageAlloc ? VINF_SUCCESS : VERR_NO_EXEC_MEMORY;
    4562         SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4623        SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    45634624    }
    45644625    if (RT_FAILURE(rc))
     
    45854646
    45864647    supdrvLdrUnlock(pDevExt);
    4587     SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4648    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    45884649    return VINF_SUCCESS;
    45894650}
     
    46474708    SUPDRV_CHECK_SMAP_SETUP();
    46484709    LogFlow(("supdrvIOCtl_LdrLoad: pvImageBase=%p cbImageWithBits=%d\n", pReq->u.In.pvImageBase, pReq->u.In.cbImageWithTabs));
    4649     SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4710    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    46504711
    46514712    /*
     
    46534714     */
    46544715    supdrvLdrLock(pDevExt);
    4655     SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4716    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    46564717
    46574718    pUsage = pSession->pLdrUsage;
     
    47424803    if (RT_FAILURE(rc))
    47434804        return rc;
    4744     SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4805    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    47454806
    47464807    /*
     
    47564817        else
    47574818            rc = /*VERR_NO_MEMORY*/ VERR_INTERNAL_ERROR_3;
    4758         SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4819        SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    47594820    }
    47604821
     
    47684829        else
    47694830            rc = /*VERR_NO_MEMORY*/ VERR_INTERNAL_ERROR_4;
    4770         SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4831        SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    47714832    }
    47724833
     
    47874848            Log(("vboxdrv: Loaded '%s' at %p\n", pImage->szName, pImage->pvImage));
    47884849        }
    4789         SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4850        SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    47904851    }
    47914852
     
    48214882        pDevExt->pLdrInitImage  = pImage;
    48224883        pDevExt->hLdrInitThread = RTThreadNativeSelf();
    4823         SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4884        SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    48244885        rc = pImage->pfnModuleInit(pImage);
    4825         SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4886        SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    48264887        pDevExt->pLdrInitImage  = NULL;
    48274888        pDevExt->hLdrInitThread = NIL_RTNATIVETHREAD;
     
    48494910
    48504911    supdrvLdrUnlock(pDevExt);
    4851     SUPDRV_CHECK_SMAP_CHECK(RT_NOTHING);
     4912    SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
    48524913    return rc;
    48534914}
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r57218 r57229  
    215215 *          - nothing.
    216216 */
    217 #define SUPDRV_IOC_VERSION                              0x00230002
     217#define SUPDRV_IOC_VERSION                              0x00230003
    218218
    219219/** SUP_IOCTL_COOKIE. */
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r57224 r57229  
    625625    /** @} */
    626626
     627    /** Number of times someone reported bad execution context via SUPR0BadContext.
     628     * (This is times EFLAGS.AC is zero when we expected it to be 1.) */
     629    uint32_t volatile               cBadContextCalls;
    627630
    628631    /** GIP mutex.
     
    952955uint32_t VBOXCALL supdrvSessionRetain(PSUPDRVSESSION pSession);
    953956uint32_t VBOXCALL supdrvSessionRelease(PSUPDRVSESSION pSession);
     957void VBOXCALL   supdrvBadContext(PSUPDRVDEVEXT pDevExt, const char *pszFile, uint32_t uLine, const char *pszExtra);
    954958int VBOXCALL    supdrvQueryVTCapsInternal(uint32_t *pfCaps);
    955959
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r57218 r57229  
    280280        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    281281        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00230000
    282                                    ? 0x00230000
     282                                   ? 0x00230003
    283283                                   : SUPDRV_IOC_VERSION & 0xffff0000;
    284284        CookieReq.u.In.u32MinVersion = uMinVersion;
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp

    r57220 r57229  
    7979#endif
    8080
    81 /* Temporary debugging. */
     81/* The following macros are duplicated in the-darwin-kernel.h. */
     82#define IPRT_DARWIN_SAVE_EFL_AC()           RTCCUINTREG const fSavedEfl = ASMGetFlags();
     83#define IPRT_DARWIN_RESTORE_EFL_AC()        ASMSetFlags(fSavedEfl)
     84#define IPRT_DARWIN_RESTORE_EFL_ONLY_AC()   ASMChangeFlags(~X86_EFL_AC, fSavedEfl & X86_EFL_AC)
     85
     86
     87/* Temporary debugging - very temporary... */
    8288#define VBOX_PROC_SELFNAME_LEN  (20)
    83 #define VBOX_RETRIEVE_CUR_PROC_NAME(_name)    char _name[VBOX_PROC_SELFNAME_LEN]; \
    84                                               proc_selfname(pszProcName, VBOX_PROC_SELFNAME_LEN)
     89#define VBOX_RETRIEVE_CUR_PROC_NAME(_name)  char _name[VBOX_PROC_SELFNAME_LEN]; \
     90                                            proc_selfname(pszProcName, VBOX_PROC_SELFNAME_LEN)
    8591
    8692
     
    586592    PSUPDRVSESSION      pSession;
    587593
     594#ifdef VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV
     595    /*
     596     * Refuse all I/O control calls if we've ever detected EFLAGS.AC being cleared.
     597     *
     598     * This isn't a problem, as there is absolutely nothing in the kernel context that
     599     * depend on user context triggering cleanups.  That would be pretty wild, right?
     600     */
     601    if (RT_UNLIKELY(g_DevExt.cBadContextCalls > 0))
     602    {
     603        SUPR0Printf("VBoxDrvDarwinIOCtl: EFLAGS.AC=0 detected %u times, refusing all I/O controls!\n", g_DevExt.cBadContextCalls);
     604        return EDEVERR;
     605    }
     606#endif
     607
    588608    /*
    589609     * Find the session.
     
    651671#if defined(VBOX_STRICT) || defined(VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV)
    652672    if (RT_UNLIKELY(!(ASMGetFlags() & X86_EFL_AC)))
    653         SUPR0Printf("VBoxDrvDarwinIOCtlSMAP: someone cleared AC handling iCmd=%#lx\n", iCmd);
     673        supdrvBadContext(&g_DevExt, "SUPDrv-darwin.cpp",  __LINE__, "VBoxDrvDarwinIOCtlSMAP");
    654674#endif
    655675    ASMSetFlags(fSavedEfl);
     
    14351455RTDECL(int) SUPR0Printf(const char *pszFormat, ...)
    14361456{
     1457    IPRT_DARWIN_SAVE_EFL_AC();
    14371458    va_list     va;
    14381459    char        szMsg[512];
     
    14441465
    14451466    printf("%s", szMsg);
     1467
     1468    IPRT_DARWIN_RESTORE_EFL_AC();
    14461469    return 0;
    14471470}
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