From 903bb1c887ea14156e7b7f153e1b443fcb31e54f Mon Sep 17 00:00:00 2001 From: Sir Richard Date: Sun, 12 Sep 2010 19:10:27 +0000 Subject: [PATCH] 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. svn path=/trunk/; revision=48759 --- reactos/ntoskrnl/mm/ARM3/pagfault.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index 8627cdeebe3..c391a0ad389 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -42,9 +42,14 @@ MiCheckVirtualAddress(IN PVOID VirtualAddress, 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 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction, /* 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) { -- 2.17.1