diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvmap.cpp | 72 |
1 files changed, 60 insertions, 12 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp index a2287cc1b..43651d8a6 100644 --- a/src/core/hle/service/nvdrv/devices/nvmap.cpp +++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp @@ -11,6 +11,13 @@ namespace Service::Nvidia::Devices { +namespace NvErrCodes { +enum { + OperationNotPermitted = -1, + InvalidValue = -22, +}; +} + nvmap::nvmap() = default; nvmap::~nvmap() = default; @@ -44,7 +51,11 @@ u32 nvmap::ioctl(Ioctl command, const std::vector<u8>& input, std::vector<u8>& o u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { IocCreateParams params; std::memcpy(¶ms, input.data(), sizeof(params)); + LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size); + if (!params.size) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } // Create a new nvmap object and obtain a handle to it. auto object = std::make_shared<Object>(); object->id = next_id++; @@ -55,8 +66,6 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { u32 handle = next_handle++; handles[handle] = std::move(object); - LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size); - params.handle = handle; std::memcpy(output.data(), ¶ms, sizeof(params)); @@ -66,9 +75,29 @@ u32 nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) { u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { IocAllocParams params; std::memcpy(¶ms, input.data(), sizeof(params)); + LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr); + + if (!params.handle) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } + + if ((params.align - 1) & params.align) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } + + const u32 min_alignment = 0x1000; + if (params.align < min_alignment) { + params.align = min_alignment; + } auto object = GetObject(params.handle); - ASSERT(object); + if (!object) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } + + if (object->status == Object::Status::Allocated) { + return static_cast<u32>(NvErrCodes::OperationNotPermitted); + } object->flags = params.flags; object->align = params.align; @@ -76,8 +105,6 @@ u32 nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) { object->addr = params.addr; object->status = Object::Status::Allocated; - LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr); - std::memcpy(output.data(), ¶ms, sizeof(params)); return 0; } @@ -88,8 +115,14 @@ u32 nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) { LOG_WARNING(Service_NVDRV, "called"); + if (!params.handle) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } + auto object = GetObject(params.handle); - ASSERT(object); + if (!object) { + return static_cast<u32>(NvErrCodes::OperationNotPermitted); + } params.id = object->id; @@ -105,7 +138,14 @@ u32 nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output) { auto itr = std::find_if(handles.begin(), handles.end(), [&](const auto& entry) { return entry.second->id == params.id; }); - ASSERT(itr != handles.end()); + if (itr == handles.end()) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } + + auto& object = itr->second; + if (object->status != Object::Status::Allocated) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } itr->second->refcount++; @@ -125,8 +165,13 @@ u32 nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output) { LOG_WARNING(Service_NVDRV, "(STUBBED) called type={}", params.param); auto object = GetObject(params.handle); - ASSERT(object); - ASSERT(object->status == Object::Status::Allocated); + if (!object) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } + + if (object->status != Object::Status::Allocated) { + return static_cast<u32>(NvErrCodes::OperationNotPermitted); + } switch (static_cast<ParamTypes>(params.param)) { case ParamTypes::Size: @@ -163,9 +208,12 @@ u32 nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) { LOG_WARNING(Service_NVDRV, "(STUBBED) called"); auto itr = handles.find(params.handle); - ASSERT(itr != handles.end()); - - ASSERT(itr->second->refcount > 0); + if (itr == handles.end()) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } + if (!itr->second->refcount) { + return static_cast<u32>(NvErrCodes::InvalidValue); + } itr->second->refcount--; |