From 02bcf98b8cfa2c00f7a8e2b1ede8ae96c70b0549 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Sat, 2 Oct 2021 00:15:53 +0530 Subject: [PATCH] Fix NvDrv Bugs + NACP Parsing Bug A hotfix for a nvdrv bug where an IOCTL with no input/output buffers would crash and a major `nvmap` bug which broke the `FromId` IOCTL as it didn't write back the handle ID, another minor bug existed in `nvhost` where the `ZCullGetInfo` IOCTL was `INOUT` rather than `OUT`. A bug with NACPs was also fixed caused by incorrect padding for the `NacpData` structure which resulted in the `saveDataOwnerId` member being read incorrectly and as a result the save data folder being incorrect. Co-authored-by: artem8086 --- app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp | 6 +++--- .../cpp/skyline/services/nvdrv/devices/nvhost/ctrl_gpu.cpp | 2 +- app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp | 6 +++++- app/src/main/cpp/skyline/vfs/nacp.h | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp b/app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp index 535195d1..7cc0925a 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/INvDrvServices.cpp @@ -59,7 +59,7 @@ namespace skyline::service::nvdrv { auto fd{request.Pop()}; auto ioctl{request.Pop()}; - auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))}; + auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span{})}; if (!buf) return NVRESULT(buf); else @@ -104,7 +104,7 @@ namespace skyline::service::nvdrv { // Inline buffer is optional auto inlineBuf{request.inputBuf.size() > 1 ? request.inputBuf.at(1) : span{}}; - auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))}; + auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span{})}; if (!buf) return NVRESULT(buf); else @@ -118,7 +118,7 @@ namespace skyline::service::nvdrv { // Inline buffer is optional auto inlineBuf{request.outputBuf.size() > 1 ? request.outputBuf.at(1) : span{}}; - auto buf{GetMainIoctlBuffer(ioctl, request.inputBuf.at(0), request.outputBuf.at(0))}; + auto buf{GetMainIoctlBuffer(ioctl, !request.inputBuf.empty() ? request.inputBuf.at(0) : span{}, !request.outputBuf.empty() ? request.outputBuf.at(0) : span{})}; if (!buf) return NVRESULT(buf); else diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/ctrl_gpu.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/ctrl_gpu.cpp index e8301071..eeaee9f3 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/ctrl_gpu.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/ctrl_gpu.cpp @@ -68,7 +68,7 @@ namespace skyline::service::nvdrv::device::nvhost { IOCTL_HANDLER_FUNC(CtrlGpu, ({ IOCTL_CASE_ARGS(OUT, SIZE(0x4), MAGIC(CtrlGpuMagic), FUNC(0x1), ZCullGetCtxSize, ARGS(Out)) - IOCTL_CASE_ARGS(INOUT, SIZE(0x28), MAGIC(CtrlGpuMagic), FUNC(0x2), + IOCTL_CASE_ARGS(OUT, SIZE(0x28), MAGIC(CtrlGpuMagic), FUNC(0x2), ZCullGetInfo, ARGS(Out)) IOCTL_CASE_ARGS(INOUT, SIZE(0xB0), MAGIC(CtrlGpuMagic), FUNC(0x5), GetCharacteristics, ARGS(InOut, In, Out)) diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp index bafe5a85..7a0bfe47 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvmap.cpp @@ -31,7 +31,11 @@ namespace skyline::service::nvdrv::device { if (!handleDesc) [[unlikely]] return PosixResult::InvalidArgument; - return handleDesc->Duplicate(ctx.internalSession); + auto result{handleDesc->Duplicate(ctx.internalSession)}; + if (result == PosixResult::Success) + handle = id; + + return result; } PosixResult NvMap::Alloc(In handle, In heapMask, In flags, InOut align, In kind, In address) { diff --git a/app/src/main/cpp/skyline/vfs/nacp.h b/app/src/main/cpp/skyline/vfs/nacp.h index 0b144583..79bf30bb 100644 --- a/app/src/main/cpp/skyline/vfs/nacp.h +++ b/app/src/main/cpp/skyline/vfs/nacp.h @@ -27,9 +27,9 @@ namespace skyline::vfs { std::array titleEntries; //!< Title entries for each language u8 _pad0_[0x2C]; u32 supportedLanguageFlag; //!< A bitmask containing the game's supported languages - u8 _pad1_[0x78]; + u8 _pad1_[0x48]; u64 saveDataOwnerId; //!< The ID that should be used for this application's savedata - u8 _pad2_[0x48]; + u8 _pad2_[0x78]; std::array seedForPseudoDeviceId; //!< Seed that is combined with the device seed for generating the pseudo-device ID u8 _pad3_[0xF00]; } nacpContents{};