Author: sir_richard
Date: Sun Sep 12 19:10:27 2010
New Revision: 48759
URL:
http://svn.reactos.org/svn/reactos?rev=48759&view=rev
Log:
Likely fix for bug 5600:
[NTOS]: Using IsBadRead/CodePtr, it's possible for user-mode code to generate cases
where we *think* this is an ARM3-managed piece of VA, which will always have a VAD (Since
we only manage the PEB/TEB), but actually it's a bogus VA-looking address that is
actually invalid. We didn't consider this case. We now implement the same code Windows
normally would also handle, when the VA is bogus, and accept that no VAD might be found,
so MM_NOACCESS is returned and thus an access violation sent to the caller. In the case of
the IsBad...Ptr, this function would then return TRUE, as the caller expects.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Sun Sep 12 19:10:27 2010
@@ -42,9 +42,14 @@
return MmSharedUserDataPte;
}
- /* Find the VAD, it must exist, since we only handle PEB/TEB */
+ /* Find the VAD, it might not exist if the address is bogus */
Vad = MiLocateAddress(VirtualAddress);
- ASSERT(Vad);
+ if (!Vad)
+ {
+ /* Bogus virtual address */
+ *ProtectCode = MM_NOACCESS;
+ return NULL;
+ }
/* This must be a TEB/PEB VAD */
ASSERT(Vad->u.VadFlags.PrivateMemory == TRUE);
@@ -726,8 +731,23 @@
/* Check if this address range belongs to a valid allocation (VAD) */
ProtoPte = MiCheckVirtualAddress(Address, &ProtectionCode, &Vad);
- ASSERT(ProtectionCode != MM_NOACCESS);
-
+ if (ProtectionCode == MM_NOACCESS)
+ {
+ /* This is a bogus VA */
+ Status = STATUS_ACCESS_VIOLATION;
+
+ /* Could be a not-yet-mapped paged pool page table */
+#if (_MI_PAGING_LEVELS == 2)
+ MiCheckPdeForPagedPool(Address);
+#endif
+ /* See if that fixed it */
+ if (PointerPte->u.Hard.Valid == 1) Status = STATUS_SUCCESS;
+
+ /* Return the status */
+ MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
+ return Status;
+ }
+
/* Did we get a prototype PTE back? */
if (!ProtoPte)
{