Fix partial unmap reprotection on Windows (#3702)

This commit is contained in:
gdkchan 2022-09-14 12:46:37 -03:00 committed by GitHub
parent 8e119a1e96
commit 356e480bf5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -73,7 +73,7 @@ namespace Ryujinx.Memory.WindowsShared
lock (_protections) lock (_protections)
{ {
_protections.Add(new RangeNode<MemoryPermission>(address, size, MemoryPermission.None)); _protections.Add(new RangeNode<MemoryPermission>(address, address + size, MemoryPermission.None));
} }
} }
@ -132,7 +132,7 @@ namespace Ryujinx.Memory.WindowsShared
try try
{ {
UnmapViewInternal(sharedMemory, location, size, owner, updateProtection: false); UnmapViewInternal(sharedMemory, location, size, owner, updateProtection: false);
MapViewInternal(sharedMemory, srcOffset, location, size); MapViewInternal(sharedMemory, srcOffset, location, size, updateProtection: true);
} }
finally finally
{ {
@ -147,8 +147,9 @@ namespace Ryujinx.Memory.WindowsShared
/// <param name="srcOffset">Offset in the shared memory to map</param> /// <param name="srcOffset">Offset in the shared memory to map</param>
/// <param name="location">Address to map the view into</param> /// <param name="location">Address to map the view into</param>
/// <param name="size">Size of the view in bytes</param> /// <param name="size">Size of the view in bytes</param>
/// <param name="updateProtection">Indicates if the memory protections should be updated after the map</param>
/// <exception cref="WindowsApiException">Thrown when the Windows API returns an error mapping the memory</exception> /// <exception cref="WindowsApiException">Thrown when the Windows API returns an error mapping the memory</exception>
private void MapViewInternal(IntPtr sharedMemory, ulong srcOffset, IntPtr location, IntPtr size) private void MapViewInternal(IntPtr sharedMemory, ulong srcOffset, IntPtr location, IntPtr size, bool updateProtection)
{ {
SplitForMap((ulong)location, (ulong)size, srcOffset); SplitForMap((ulong)location, (ulong)size, srcOffset);
@ -168,8 +169,11 @@ namespace Ryujinx.Memory.WindowsShared
throw new WindowsApiException("MapViewOfFile3"); throw new WindowsApiException("MapViewOfFile3");
} }
if (updateProtection)
{
UpdateProtection((ulong)location, (ulong)size, MemoryPermission.ReadAndWrite); UpdateProtection((ulong)location, (ulong)size, MemoryPermission.ReadAndWrite);
} }
}
/// <summary> /// <summary>
/// Splits a larger placeholder, slicing at the start and end address, for a new memory mapping. /// Splits a larger placeholder, slicing at the start and end address, for a new memory mapping.
@ -330,7 +334,7 @@ namespace Ryujinx.Memory.WindowsShared
{ {
ulong remapSize = startAddress - overlap.Start; ulong remapSize = startAddress - overlap.Start;
MapViewInternal(sharedMemory, overlap.Value, (IntPtr)overlap.Start, (IntPtr)remapSize); MapViewInternal(sharedMemory, overlap.Value, (IntPtr)overlap.Start, (IntPtr)remapSize, updateProtection: false);
RestoreRangeProtection(overlap.Start, remapSize); RestoreRangeProtection(overlap.Start, remapSize);
} }
@ -341,7 +345,7 @@ namespace Ryujinx.Memory.WindowsShared
ulong remapAddress = overlap.Start + overlappedSize; ulong remapAddress = overlap.Start + overlappedSize;
ulong remapSize = overlap.End - endAddress; ulong remapSize = overlap.End - endAddress;
MapViewInternal(sharedMemory, remapBackingOffset, (IntPtr)remapAddress, (IntPtr)remapSize); MapViewInternal(sharedMemory, remapBackingOffset, (IntPtr)remapAddress, (IntPtr)remapSize, updateProtection: false);
RestoreRangeProtection(remapAddress, remapSize); RestoreRangeProtection(remapAddress, remapSize);
} }
} }
@ -606,7 +610,7 @@ namespace Ryujinx.Memory.WindowsShared
_protections.Remove(protection); _protections.Remove(protection);
if (protection.Value == permission) if (protPermission == permission)
{ {
if (startAddress > protAddress) if (startAddress > protAddress)
{ {