VirtualBox

Changeset 65178 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jan 6, 2017 10:29:41 AM (8 years ago)
Author:
vboxsync
Message:

IEM: Call gate must take current stack size into account and not commit state until after #PF checks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r65168 r65178  
    13871387             *         then switched. According to AMD, the stack is switched first and
    13881388             *         then pushes might fault!
     1389             *         NB: OS/2 Warp 3/4 actively relies on the fact that possible
     1390             *         incoming stack #PF happens before actual stack switch. AMD is
     1391             *         either lying or implicitly assumes that new state is committed
     1392             *         only if and when an instruction doesn't fault.
    13891393             */
    13901394
     
    14061410            /* Remember the old SS:rSP and their linear address. */
    14071411            uOldSS  = pCtx->ss.Sel;
    1408             uOldRsp = pCtx->rsp;
    1409 
    1410             GCPtrParmWds = pCtx->ss.u64Base + pCtx->rsp;
     1412            uOldRsp = pCtx->ss.Attr.n.u1DefBig ? pCtx->rsp : pCtx->sp;
     1413
     1414            GCPtrParmWds = pCtx->ss.u64Base + uOldRsp;
     1415
     1416            /* Probe if the write to the new stack will succeed. May #SS(NewSS) or #PF. */
     1417            void     *pvNewFrame;
     1418            RTGCPTR  GCPtrNewStack = X86DESC_BASE(&DescSS.Legacy) + uNewRsp - cbNewStack;
     1419            rcStrict = iemMemMap(pVCpu, &pvNewFrame, cbNewStack, UINT8_MAX, GCPtrNewStack, IEM_ACCESS_SYS_RW);
     1420            if (rcStrict != VINF_SUCCESS)
     1421            {
     1422                Log(("BranchCallGate: Incoming stack (%04x:%08RX64) not accessible, rc=%Rrc\n", uNewSS, uNewRsp, VBOXSTRICTRC_VAL(rcStrict)));
     1423                return rcStrict;
     1424            }
     1425            rcStrict = iemMemCommitAndUnmap(pVCpu, pvNewFrame, IEM_ACCESS_SYS_RW);
     1426            if (rcStrict != VINF_SUCCESS)
     1427            {
     1428                Log(("BranchCallGate: New stack probe unmapping failed (%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict)));
     1429                return rcStrict;
     1430            }
    14111431
    14121432            /* Commit new SS:rSP. */
     
    14181438            pCtx->ss.fFlags   = CPUMSELREG_FLAGS_VALID;
    14191439            pCtx->rsp         = uNewRsp;
    1420             pVCpu->iem.s.uCpl     = uNewCSDpl;
     1440            pVCpu->iem.s.uCpl = uNewCSDpl;
    14211441            Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->ss));
    14221442            CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_HIDDEN_SEL_REGS);
    14231443
    1424             /* Check new stack - may #SS(NewSS). */
     1444            /* At this point the stack access must not fail because new state was already committed. */
    14251445            rcStrict = iemMemStackPushBeginSpecial(pVCpu, cbNewStack,
    14261446                                                   &uPtrRet.pv, &uNewRsp);
    1427             if (rcStrict != VINF_SUCCESS)
    1428             {
    1429                 Log(("BranchCallGate: New stack mapping failed (%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict)));
    1430                 return rcStrict;
    1431             }
     1447            AssertMsgReturn(rcStrict == VINF_SUCCESS, ("BranchCallGate: New stack mapping failed (%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict)),
     1448                            VERR_IPE_UNEXPECTED_STATUS);
    14321449
    14331450            if (!IEM_IS_LONG_MODE(pVCpu))
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