Bug inside VirtualAllocEx function Windows CE 7.0 RRS feed

  • Question

  • Bug inside VirtualAllocEx function Windows CE 7.0

    I want to report a bug inside VirtualAllocEx functionality inside Windows Embedded CE 7.0 kernel.
    I got a problem with VirtualAllocEx function few days ago.

    The problem appears as "Data Abort" exception inside CommitPages() function (in kernel.dll).
    In worst case it can fill some memory by zeros in another process.
    If this bug appear, DoVMAlloc() and then VirtualAllocEx() fails.
    It seems that problem only caused by VirtualAllocEx call from kernel mode to allocate memory inside user mode process.

    I had looked a bit inside and seems was able to find rootcase of this issue:

    1. Inside DoVMAlloc() it calls SwitchVM(), if the current memory space doesn't match the desired one.
    2. Enumerate2ndPT() calls calback CommitPages(), inside callback it sometimes needs to clear page with zeros (this functionality was not present inside CE 6.0 kernel)

    3. Kernel threads has zero initial value for "pprcVM" field.
    A special check inside SetCPUASID() function forces such thread to keep old (which was active before) memory space.

    The fault condition happens if:
    *We have ProcA process.
    *We have ThreadA kernel thread.

    *During scheduling ppcb->pVMPrc got pointer to ProcA
    *ThreadA has zero value in pprcVM field, because it's kernel one.

    *Several other kernel threads was scheduled to run.
    This means that SetCPUASID() didn't change ppcb->pVMPrc value and it still points to ProcA structure. ThreadA still has zero value in pprcVM field.

    *ThreadA calls VirtualAllocEx to allocate memory inside process.
    SwitchVM() is not called inside DoVMAlloc(), because destination process is same with ppcb->pVMPrc. ThreadA still has zero value in pprcVM field.

    *During Enumerate2ndPT() or CommitPages() code execution ThreadA was preempted by another user thread. This actually means that SetCPUASID() function changed ppcb->pVMPrc value as well active memory mapping.

    *ThreadA gain execution back, it's inside CommitPages() or Enumerate2ndPT().
    But the memory mapping now is different from destination process.
    So "ZeroPage ((LPVOID) pvs->dwAddr);" construction tries to erase memory inside another process, not inside the destination process for VirtualAllocEx call. This causes wrong memory operations or DataAbort.

    Can you check that and confirm that?

    Sunday, May 20, 2012 11:37 PM