From 9ef25a6beb188093f8439a7e933463702ca0285c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=97=B1=20PixelyIon?= Date: Sun, 5 Jul 2020 13:12:30 +0100 Subject: [PATCH] IPC bug fixes This fixes two bugs in IPC that were discovered when running Puyo Puyo Tetris. The CloneCurrentObject control IPC will now correctly return the handle of the newly created object through move handles, rather than pushing it as a result. The size array of u16s with the sizes of each C buffer is now taken into account when reading them. Before this change C buffers were entirely broken. --- app/src/main/cpp/skyline/kernel/ipc.cpp | 8 +++++--- app/src/main/cpp/skyline/services/serviceman.cpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/cpp/skyline/kernel/ipc.cpp b/app/src/main/cpp/skyline/kernel/ipc.cpp index 5c3e5543..e7d3a31f 100644 --- a/app/src/main/cpp/skyline/kernel/ipc.cpp +++ b/app/src/main/cpp/skyline/kernel/ipc.cpp @@ -22,6 +22,8 @@ namespace skyline::kernel::ipc { header = reinterpret_cast(pointer); pointer += sizeof(CommandHeader); + size_t cBufferLengthSize = util::AlignUp(((header->cFlag == BufferCFlag::None) ? 0 : ((header->cFlag > BufferCFlag::SingleDescriptor) ? (static_cast(header->cFlag) - 2) : 1)) * sizeof(u16), sizeof(u32)); + if (header->handleDesc) { handleDesc = reinterpret_cast(pointer); pointer += sizeof(HandleDescriptor) + (handleDesc->sendPid ? sizeof(u64) : 0); @@ -85,7 +87,7 @@ namespace skyline::kernel::ipc { cmdArg = pointer; cmdArgSz = domain->payloadSz - sizeof(PayloadHeader); - pointer += domain->payloadSz; + pointer += cmdArgSz; for (u8 index = 0; domain->inputCount > index; index++) { domainObjects.push_back(*reinterpret_cast(pointer)); @@ -96,7 +98,7 @@ namespace skyline::kernel::ipc { pointer += sizeof(PayloadHeader); cmdArg = pointer; - cmdArgSz = (header->rawSize * sizeof(u32)) - (constant::IpcPaddingSum + sizeof(PayloadHeader)); + cmdArgSz = (header->rawSize * sizeof(u32)) - (constant::IpcPaddingSum + sizeof(PayloadHeader)) - cBufferLengthSize; pointer += cmdArgSz; } @@ -105,7 +107,7 @@ namespace skyline::kernel::ipc { if (payload->magic != util::MakeMagic("SFCI") && (header->type != CommandType::Control && header->type != CommandType::ControlWithContext)) // SFCI is the magic in received IPC messages state.logger->Debug("Unexpected Magic in PayloadHeader: 0x{:X}", u32(payload->magic)); - pointer += constant::IpcPaddingSum - padding; + pointer += constant::IpcPaddingSum - padding + cBufferLengthSize; if (header->cFlag == BufferCFlag::SingleDescriptor) { auto bufC = reinterpret_cast(pointer); diff --git a/app/src/main/cpp/skyline/services/serviceman.cpp b/app/src/main/cpp/skyline/services/serviceman.cpp index 08b0289c..a931a66b 100644 --- a/app/src/main/cpp/skyline/services/serviceman.cpp +++ b/app/src/main/cpp/skyline/services/serviceman.cpp @@ -189,7 +189,7 @@ namespace skyline::service { break; case ipc::ControlCommand::CloneCurrentObject: case ipc::ControlCommand::CloneCurrentObjectEx: - response.Push(state.process->InsertItem(session)); + response.moveHandles.push_back(state.process->InsertItem(session)); break; case ipc::ControlCommand::QueryPointerBufferSize: response.Push(0x1000);