diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-03-10 20:39:16 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-03-10 20:39:16 -0300 |
| commit | 3777fb44cf03d05fdedee00f1a19d30fac73b31b (patch) | |
| tree | 315dc98309bc19c05ee6ac79d1648ddfa2a87964 /Ryujinx.Core/OsHle | |
| parent | 553f6c2976818b3abcd0fd09de582dc71f03736e (diff) | |
Allow to enable/disable memory checks even on release mode through the flag, return error for invalid addresses on SvcMap*Memory svcs, do not return error on SvcQueryMemory (instead, return reserved for the end of the address space), other minor tweaks
Diffstat (limited to 'Ryujinx.Core/OsHle')
| -rw-r--r-- | Ryujinx.Core/OsHle/Horizon.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Ipc/IpcMessage.cs | 14 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs | 42 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Svc/SvcMemory.cs | 107 |
4 files changed, 129 insertions, 36 deletions
diff --git a/Ryujinx.Core/OsHle/Horizon.cs b/Ryujinx.Core/OsHle/Horizon.cs index a8f5df7c..c61e18e9 100644 --- a/Ryujinx.Core/OsHle/Horizon.cs +++ b/Ryujinx.Core/OsHle/Horizon.cs @@ -52,6 +52,8 @@ namespace Ryujinx.Core.OsHle HidHandle = Handles.GenerateId(HidSharedMem); FontHandle = Handles.GenerateId(new HSharedMem()); + + HidSharedMem.AddVirtualPosition(0); } public void LoadCart(string ExeFsDir, string RomFsFile = null) diff --git a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs index cc26df10..ebb3dbca 100644 --- a/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs +++ b/Ryujinx.Core/OsHle/Ipc/IpcMessage.cs @@ -217,16 +217,26 @@ namespace Ryujinx.Core.OsHle.Ipc public long GetSendBuffPtr() { - if (SendBuff.Count > 0 && SendBuff[0].Position != 0) + if (SendBuff.Count > 0 && SendBuff[0].Size != 0) { return SendBuff[0].Position; } - if (PtrBuff.Count > 0 && PtrBuff[0].Position != 0) + if (PtrBuff.Count > 0 && PtrBuff[0].Size != 0) { return PtrBuff[0].Position; } + if (ReceiveBuff.Count > 0 && ReceiveBuff[0].Size != 0) + { + return ReceiveBuff[0].Position; + } + + if (RecvListBuff.Count > 0 && RecvListBuff[0].Size != 0) + { + return RecvListBuff[0].Position; + } + return -1; } } diff --git a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs index 515c15e0..3c0c46fe 100644 --- a/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs +++ b/Ryujinx.Core/OsHle/Services/Nv/ServiceNvDrv.cs @@ -81,7 +81,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices FileDesc FdData = Context.Ns.Os.Fds.GetData<FileDesc>(Fd); - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); Context.ResponseData.Write(0); @@ -139,7 +139,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlBindChannel(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); int Fd = Context.Memory.ReadInt32(Position); @@ -148,7 +148,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlAllocSpace(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -174,7 +174,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlMapBufferEx(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -207,7 +207,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlGetVaRegions(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position); @@ -237,7 +237,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuAsIoctlInitializeEx(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -254,7 +254,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvHostIoctlCtrlGetConfig(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position + 0x82); @@ -269,7 +269,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvHostIoctlCtrlEventWait(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -285,7 +285,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlZcullGetCtxSize(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); Context.Memory.WriteInt32(Position, 1); @@ -294,7 +294,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlZcullGetInfo(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemWriter Writer = new MemWriter(Context.Memory, Position); @@ -314,7 +314,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlGetCharacteristics(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position); @@ -376,7 +376,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlGetTpcMasks(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -390,7 +390,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvGpuIoctlZbcGetActiveSlotMask(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); Context.Memory.WriteInt32(Position + 0, 7); Context.Memory.WriteInt32(Position + 4, 1); @@ -400,14 +400,14 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelSetUserData(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); return 0; } private static long NvMapIoctlChannelSetNvMap(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); int Fd = Context.Memory.ReadInt32(Position); @@ -416,7 +416,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelSubmitGpFifo(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position + 0x10); @@ -455,7 +455,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelAllocObjCtx(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); int ClassNum = Context.Memory.ReadInt32(Position + 0); int Flags = Context.Memory.ReadInt32(Position + 4); @@ -467,7 +467,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelZcullBind(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -480,7 +480,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelSetErrorNotifier(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); @@ -494,7 +494,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelSetPriority(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); int Priority = Context.Memory.ReadInt32(Position); @@ -503,7 +503,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.NvServices private static long NvMapIoctlChannelAllocGpFifoEx2(ServiceCtx Context) { - long Position = Context.Request.PtrBuff[0].Position; + long Position = Context.Request.GetSendBuffPtr(); MemReader Reader = new MemReader(Context.Memory, Position); MemWriter Writer = new MemWriter(Context.Memory, Position + 0xc); diff --git a/Ryujinx.Core/OsHle/Svc/SvcMemory.cs b/Ryujinx.Core/OsHle/Svc/SvcMemory.cs index bf946e4f..c15f449b 100644 --- a/Ryujinx.Core/OsHle/Svc/SvcMemory.cs +++ b/Ryujinx.Core/OsHle/Svc/SvcMemory.cs @@ -55,6 +55,24 @@ namespace Ryujinx.Core.OsHle.Svc long Src = (long)ThreadState.X1; long Size = (long)ThreadState.X2; + if (!IsValidPosition(Src)) + { + Logging.Warn($"Tried to map Memory at invalid src address {Src:x16}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); + + return; + } + + if (!IsValidMapPosition(Dst)) + { + Logging.Warn($"Tried to map Memory at invalid dst address {Dst:x16}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); + + return; + } + AMemoryMapInfo SrcInfo = Memory.Manager.GetMapInfo(Src); Memory.Manager.Map(Dst, Size, (int)MemoryType.MappedMemory, SrcInfo.Perm); @@ -72,6 +90,24 @@ namespace Ryujinx.Core.OsHle.Svc long Src = (long)ThreadState.X1; long Size = (long)ThreadState.X2; + if (!IsValidPosition(Src)) + { + Logging.Warn($"Tried to unmap Memory at invalid src address {Src:x16}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); + + return; + } + + if (!IsValidMapPosition(Dst)) + { + Logging.Warn($"Tried to unmap Memory at invalid dst address {Dst:x16}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); + + return; + } + AMemoryMapInfo DstInfo = Memory.Manager.GetMapInfo(Dst); Memory.Manager.Unmap(Dst, Size, (int)MemoryType.MappedMemory); @@ -92,9 +128,11 @@ namespace Ryujinx.Core.OsHle.Svc if (MapInfo == null) { - ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); + long AddrSpaceEnd = MemoryRegions.AddrSpaceStart + MemoryRegions.AddrSpaceSize; - return; + long ReservedSize = (long)(ulong.MaxValue - (ulong)AddrSpaceEnd) + 1; + + MapInfo = new AMemoryMapInfo(AddrSpaceEnd, ReservedSize, (int)MemoryType.Reserved, 0, AMemoryPerm.None); } Memory.WriteInt64(InfoPtr + 0x00, MapInfo.Position); @@ -118,15 +156,26 @@ namespace Ryujinx.Core.OsHle.Svc long Size = (long)ThreadState.X2; int Perm = (int)ThreadState.X3; + if (!IsValidPosition(Src)) + { + Logging.Warn($"Tried to map SharedMemory at invalid address {Src:x16}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); + + return; + } + HSharedMem SharedMem = Ns.Os.Handles.GetData<HSharedMem>(Handle); if (SharedMem != null) { + Memory.Manager.Map(Src, Size, (int)MemoryType.SharedMemory, AMemoryPerm.Write); + AMemoryHelper.FillWithZeros(Memory, Src, (int)Size); - SharedMem.AddVirtualPosition(Src); + Memory.Manager.Reprotect(Src, Size, (AMemoryPerm)Perm); - Memory.Manager.Map(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); + SharedMem.AddVirtualPosition(Src); ThreadState.X0 = 0; } @@ -136,14 +185,25 @@ namespace Ryujinx.Core.OsHle.Svc private void SvcUnmapSharedMemory(AThreadState ThreadState) { - int Handle = (int)ThreadState.X0; - long Position = (long)ThreadState.X1; - long Size = (long)ThreadState.X2; + int Handle = (int)ThreadState.X0; + long Src = (long)ThreadState.X1; + long Size = (long)ThreadState.X2; + + if (!IsValidPosition(Src)) + { + Logging.Warn($"Tried to unmap SharedMemory at invalid address {Src:x16}!"); + + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); + + return; + } HSharedMem HndData = Ns.Os.Handles.GetData<HSharedMem>(Handle); if (HndData != null) { + Memory.Manager.Unmap(Src, Size, (int)MemoryType.SharedMemory); + ThreadState.X0 = 0; } @@ -152,20 +212,41 @@ namespace Ryujinx.Core.OsHle.Svc private void SvcCreateTransferMemory(AThreadState ThreadState) { - long Position = (long)ThreadState.X1; - long Size = (long)ThreadState.X2; - int Perm = (int)ThreadState.X3; + long Src = (long)ThreadState.X1; + long Size = (long)ThreadState.X2; + int Perm = (int)ThreadState.X3; - AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Position); + if (!IsValidPosition(Src)) + { + Logging.Warn($"Tried to create TransferMemory at invalid address {Src:x16}!"); - Memory.Manager.Reprotect(Position, Size, (AMemoryPerm)Perm); + ThreadState.X0 = MakeError(ErrorModule.Kernel, KernelErr.InvalidMemRange); + + return; + } - HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Position, Size); + AMemoryMapInfo MapInfo = Memory.Manager.GetMapInfo(Src); + + Memory.Manager.Reprotect(Src, Size, (AMemoryPerm)Perm); + + HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Src, Size); int Handle = Ns.Os.Handles.GenerateId(HndData); ThreadState.X1 = (ulong)Handle; ThreadState.X0 = 0; } + + private static bool IsValidPosition(long Position) + { + return Position >= MemoryRegions.AddrSpaceStart && + Position < MemoryRegions.AddrSpaceStart + MemoryRegions.AddrSpaceSize; + } + + private static bool IsValidMapPosition(long Position) + { + return Position >= MemoryRegions.MapRegionAddress && + Position < MemoryRegions.MapRegionAddress + MemoryRegions.MapRegionSize; + } } }
\ No newline at end of file |
