Merge pull request #3788 from xXPBSXx/fix/libkernel-mprotect-host-memory-v3
fix(libkernel): allow sceKernelMprotect on committed host memory outside the guest registry
This commit is contained in:
commit
dc70a66cbd
|
|
@ -921,6 +921,10 @@ int DoMprotect(const void* addr, size_t len, int prot) {
|
|||
else if (IsGuestModuleImage(memory.AllocationBase)) mutation.RegisterImage(memory.AllocationBase);
|
||||
else throw std::invalid_argument("Memory protection of a foreign image is not supported");
|
||||
}
|
||||
if (memory.Type == MEM_PRIVATE && memory.State == MEM_COMMIT && memory.RegionSize >= bytes && !mutation.Overlaps(pointer, bytes)) {
|
||||
if (mprotect(const_cast<void*>(pointer), bytes, nativeProtection) != 0) throw std::system_error(errno, std::generic_category(), "mprotect failed");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
mutation.RegisterMainImage();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1698,12 +1698,31 @@ static void CheckAvailableDirectMemoryIsLargestFreeBlock() {
|
|||
Require(sceKernelAvailableDirectMemorySize(top, top + window, 0, &start, &size) == 0);
|
||||
Require(start == top && size == static_cast<std::size_t>(window));
|
||||
}
|
||||
#ifdef _WIN32
|
||||
static void CheckMprotectOfHostMemoryOutsideTheGuestRegistry() {
|
||||
constexpr std::size_t length = 0x40000;
|
||||
void* host = VirtualAlloc(nullptr, length, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
Require(host != nullptr);
|
||||
Require(sceKernelMprotect(host, length, 0x3) == 0);
|
||||
static_cast<volatile unsigned char*>(host)[length - 1] = 7;
|
||||
Require(static_cast<volatile unsigned char*>(host)[length - 1] == 7);
|
||||
Require(sceKernelMprotect(host, length, 0x1) == 0);
|
||||
MEMORY_BASIC_INFORMATION info{};
|
||||
Require(VirtualQuery(host, &info, sizeof(info)) == sizeof(info) && info.Protect == PAGE_READONLY);
|
||||
Require(sceKernelMprotect(host, length, 0x3) == 0);
|
||||
Require(VirtualQuery(host, &info, sizeof(info)) == sizeof(info) && info.Protect == PAGE_READWRITE);
|
||||
Require(VirtualFree(host, 0, MEM_RELEASE) != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
#ifdef _WIN32
|
||||
_putenv_s("APS5_PIN_WAIT_MS", "1000");
|
||||
#endif
|
||||
CheckAvailableDirectMemoryIsLargestFreeBlock();
|
||||
#ifdef _WIN32
|
||||
CheckMprotectOfHostMemoryOutsideTheGuestRegistry();
|
||||
#endif
|
||||
CheckVirtualQuerySplitFlexibleRanges();
|
||||
CheckVirtualQueryForNonReadableGuestRange();
|
||||
CheckReleaseFlexibleMemory();
|
||||
|
|
|
|||
Loading…
Reference in New Issue