From e3a65b14056584b712840d8ae1ecc23e7fb77424 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 8 Apr 2021 17:55:25 -0700 Subject: [PATCH] tipc: fix deserialization of buffers --- .../impl/tipc_impl_command_serialization.hpp | 30 +++++------- .../source/_test/test_tipc_serializer.cpp | 47 ++++++++++--------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/libraries/libstratosphere/include/stratosphere/tipc/impl/tipc_impl_command_serialization.hpp b/libraries/libstratosphere/include/stratosphere/tipc/impl/tipc_impl_command_serialization.hpp index d39356b53..9ef0a57a8 100644 --- a/libraries/libstratosphere/include/stratosphere/tipc/impl/tipc_impl_command_serialization.hpp +++ b/libraries/libstratosphere/include/stratosphere/tipc/impl/tipc_impl_command_serialization.hpp @@ -358,14 +358,13 @@ namespace ams::tipc::impl { } } else if constexpr (arg_type == ArgumentType::Buffer) { /* New Buffer, increment the appropriate index. */ - const auto attributes = BufferAttributes[current_info.buffer_index]; - current_info.buffer_index++; + const auto attributes = BufferAttributes[current_info.buffer_index++]; if (attributes & SfBufferAttr_In) { - current_info.is_send_buffer = true; + returned_info.is_send_buffer = true; current_info.send_map_alias_index++; } else if (attributes & SfBufferAttr_Out) { - current_info.is_send_buffer = false; + returned_info.is_send_buffer = false; current_info.recv_map_alias_index++; } } else if constexpr (arg_type == ArgumentType::ProcessId) { @@ -460,6 +459,9 @@ namespace ams::tipc::impl { } }; + template + struct PrintIndex; + template class CommandProcessor { public: @@ -533,13 +535,13 @@ namespace ams::tipc::impl { constexpr auto BufferIndex = CommandMeta::InMessageBufferIndex + (Info.send_map_alias_index * MapAliasDescriptorSize / sizeof(util::BitPack32)); const svc::ipc::MessageBuffer::MapAliasDescriptor descriptor(message_buffer, BufferIndex); - return T(tipc::PointerAndSize(descriptor.GetAddress(), descriptor.GetSize())); + return T(descriptor.GetAddress(), descriptor.GetSize()); } else { /* Input receive buffer. */ constexpr auto BufferIndex = CommandMeta::InMessageBufferIndex + ((CommandMeta::NumInBuffers + Info.recv_map_alias_index) * MapAliasDescriptorSize / sizeof(util::BitPack32)); const svc::ipc::MessageBuffer::MapAliasDescriptor descriptor(message_buffer, BufferIndex); - return T(tipc::PointerAndSize(descriptor.GetAddress(), descriptor.GetSize())); + return T(descriptor.GetAddress(), descriptor.GetSize()); } } else if constexpr (Info.arg_type == ArgumentType::ProcessId) { return T{ os::ProcessId{ message_buffer.GetProcessId(CommandMeta::InMessageProcessIdIndex) } }; @@ -547,11 +549,6 @@ namespace ams::tipc::impl { static_assert(!std::is_same::value, "Invalid ArgumentType"); } } - - template - static ALWAYS_INLINE ArgsType DeserializeArgumentsImpl(const svc::ipc::MessageBuffer &message_buffer, const OutRawHolderType &out_raw_holder, OutHandleHolderType &out_handles_holder, std::index_sequence) { - return ArgsType { DeserializeArgumentImpl(message_buffer, out_raw_holder, out_handles_holder)..., }; - } public: static ALWAYS_INLINE Result ValidateCommandFormat(const svc::ipc::MessageBuffer &message_buffer) { /* Validate the message header. */ @@ -568,8 +565,9 @@ namespace ams::tipc::impl { return ResultSuccess(); } - static ALWAYS_INLINE ArgsType DeserializeArguments(const svc::ipc::MessageBuffer &message_buffer, const OutRawHolderType &out_raw_holder, OutHandleHolderType &out_handles_holder) { - return DeserializeArgumentsImpl(message_buffer, out_raw_holder, out_handles_holder, std::make_index_sequence::value>{}); + template + static ALWAYS_INLINE auto DeserializeArgument(const svc::ipc::MessageBuffer &message_buffer, const OutRawHolderType &out_raw_holder, OutHandleHolderType &out_handles_holder) { + return DeserializeArgumentImpl(message_buffer, out_raw_holder, out_handles_holder); } static ALWAYS_INLINE void SerializeResults(const svc::ipc::MessageBuffer &message_buffer, const Result &result, const OutRawHolderType &out_raw_holder, const OutHandleHolderType &out_handles_holder) { @@ -619,12 +617,10 @@ namespace ams::tipc::impl { typename Processor::OutRawHolderType out_raw_holder; typename Processor::OutHandleHolderType out_handles_holder; const Result command_result = [&](std::index_sequence) ALWAYS_INLINE_LAMBDA { - auto args_tuple = Processor::DeserializeArguments(message_buffer, out_raw_holder, out_handles_holder); - if constexpr (ReturnsResult) { - return (object->*ServiceCommandImpl)(std::forward::type>(std::get(args_tuple))...); + return (object->*ServiceCommandImpl)(Processor::template DeserializeArgument(message_buffer, out_raw_holder, out_handles_holder)...); } else { - (object->*ServiceCommandImpl)(std::forward::type>(std::get(args_tuple))...); + (object->*ServiceCommandImpl)(Processor::template DeserializeArgument(message_buffer, out_raw_holder, out_handles_holder)...); return ResultSuccess(); } }(std::make_index_sequence::value>()); diff --git a/libraries/libstratosphere/source/_test/test_tipc_serializer.cpp b/libraries/libstratosphere/source/_test/test_tipc_serializer.cpp index fa04b9013..7fe1dd36c 100644 --- a/libraries/libstratosphere/source/_test/test_tipc_serializer.cpp +++ b/libraries/libstratosphere/source/_test/test_tipc_serializer.cpp @@ -16,14 +16,20 @@ #include #include -#define AMS_TEST_I_USER_INTERFACE_INTERFACE_INFO(C, H) \ - AMS_TIPC_METHOD_INFO(C, H, 0, Result, RegisterClient, (const tipc::ClientProcessId &client_process_id), (client_process_id)) \ - AMS_TIPC_METHOD_INFO(C, H, 1, Result, GetServiceHandle, (tipc::OutMoveHandle out_h, sm::ServiceName service), (out_h, service)) \ - AMS_TIPC_METHOD_INFO(C, H, 2, Result, RegisterService, (tipc::OutMoveHandle out_h, sm::ServiceName service, u32 max_sessions, bool is_light), (out_h, service, max_sessions, is_light)) \ - AMS_TIPC_METHOD_INFO(C, H, 3, Result, UnregisterService, (sm::ServiceName service), (service)) +#define AMS_TEST_I_USER_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_TIPC_METHOD_INFO(C, H, 0, Result, RegisterClient, (const tipc::ClientProcessId &client_process_id), (client_process_id)) \ + AMS_TIPC_METHOD_INFO(C, H, 1, Result, GetServiceHandle, (tipc::OutMoveHandle out_h, sm::ServiceName service), (out_h, service)) \ + AMS_TIPC_METHOD_INFO(C, H, 2, Result, RegisterService, (tipc::OutMoveHandle out_h, sm::ServiceName service, u32 max_sessions, bool is_light), (out_h, service, max_sessions, is_light)) \ + AMS_TIPC_METHOD_INFO(C, H, 3, Result, UnregisterService, (sm::ServiceName service), (service)) AMS_TIPC_DEFINE_INTERFACE(ams::_test::impl, IUserInterface, AMS_TEST_I_USER_INTERFACE_INTERFACE_INFO) +#define AMS_TEST_I_MANAGER_INTERFACE_INTERFACE_INFO(C, H) \ + AMS_TIPC_METHOD_INFO(C, H, 0, Result, RegisterProcess, (os::ProcessId process_id, const tipc::InBuffer acid_sac, const tipc::InBuffer aci_sac), (process_id, acid_sac, aci_sac)) \ + AMS_TIPC_METHOD_INFO(C, H, 1, Result, UnregisterProcess, (os::ProcessId process_id), (process_id)) + +AMS_TIPC_DEFINE_INTERFACE(ams::_test::impl, IManagerInterface, AMS_TEST_I_MANAGER_INTERFACE_INTERFACE_INFO) + namespace ams::_test { @@ -33,26 +39,17 @@ namespace ams::_test { Result GetServiceHandle(tipc::OutMoveHandle out_h, sm::ServiceName service); Result RegisterService(tipc::OutMoveHandle out_h, sm::ServiceName service, u32 max_sessions, bool is_light); Result UnregisterService(sm::ServiceName service); + + Result ProcessDefaultServiceCommand(const svc::ipc::MessageBuffer &message_buffer); }; static_assert(impl::IsIUserInterface); - - Result TestManualDispatch(UserInterfaceFacade *facade) { - svc::ipc::MessageBuffer message_buffer(svc::ipc::GetMessageBuffer()); - - switch (svc::ipc::MessageBuffer::MessageHeader(message_buffer).GetTag()) { - case 16: - return tipc::impl::InvokeServiceCommandImpl<16, &UserInterfaceFacade::RegisterClient, UserInterfaceFacade>(facade, message_buffer); - case 17: - return tipc::impl::InvokeServiceCommandImpl<17, &UserInterfaceFacade::GetServiceHandle, UserInterfaceFacade>(facade, message_buffer); - case 18: - return tipc::impl::InvokeServiceCommandImpl<18, &UserInterfaceFacade::RegisterService, UserInterfaceFacade>(facade, message_buffer); - case 19: - return tipc::impl::InvokeServiceCommandImpl<19, &UserInterfaceFacade::UnregisterService, UserInterfaceFacade>(facade, message_buffer); - default: - return tipc::ResultInvalidMethod(); - } - } + class ManagerInterfaceFacade { + public: + Result RegisterProcess(os::ProcessId process_id, const tipc::InBuffer acid_sac, const tipc::InBuffer aci_sac); + Result UnregisterProcess(os::ProcessId process_id); + }; + static_assert(impl::IsIManagerInterface); using UserInterfaceObject = ::ams::tipc::ServiceObject; @@ -60,5 +57,11 @@ namespace ams::_test { return object->ProcessRequest(); } + using ManagerInterfaceObject = ::ams::tipc::ServiceObject; + + Result TestManagerDispatch(ManagerInterfaceObject *object) { + return object->ProcessRequest(); + } + } \ No newline at end of file