mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
sf: prevent emitting mitm/defer code unless server in process supports it
This commit is contained in:
parent
d27fe8a229
commit
bd1bcdf52b
21 changed files with 230 additions and 107 deletions
|
@ -40,6 +40,8 @@ namespace ams::scs {
|
|||
static constexpr size_t PointerBufferSize = 0;
|
||||
static constexpr size_t MaxDomains = 6;
|
||||
static constexpr size_t MaxDomainObjects = 16;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
class ServerManager final : public sf::hipc::ServerManager<Port_Count, ServerOptions, MaxSessions> {
|
||||
|
|
|
@ -24,6 +24,8 @@ namespace ams::sf::hipc {
|
|||
static constexpr size_t PointerBufferSize = 0;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
static constexpr size_t ServerSessionCountMax = 0x40;
|
||||
|
@ -72,6 +74,9 @@ namespace ams::sf::hipc {
|
|||
R_ABORT_UNLESS(sm::mitm::AcknowledgeSession(out_fsrv->get(), out_client_info, m_service_name));
|
||||
}
|
||||
};
|
||||
protected:
|
||||
static constinit inline bool g_is_any_deferred_supported = false;
|
||||
static constinit inline bool g_is_any_mitm_supported = false;
|
||||
private:
|
||||
/* Multiple wait management. */
|
||||
os::MultiWaitType m_multi_wait;
|
||||
|
@ -84,6 +89,10 @@ namespace ams::sf::hipc {
|
|||
|
||||
os::SdkMutex m_deferred_list_mutex;
|
||||
os::MultiWaitType m_deferred_list;
|
||||
|
||||
/* Boolean values. */
|
||||
const bool m_is_defer_supported;
|
||||
const bool m_is_mitm_supported;
|
||||
private:
|
||||
virtual void RegisterServerSessionToWait(ServerSession *session) override final;
|
||||
void LinkToDeferredList(os::MultiWaitHolderType *holder);
|
||||
|
@ -102,6 +111,7 @@ namespace ams::sf::hipc {
|
|||
server->m_is_mitm_server = is_mitm_server;
|
||||
if (is_mitm_server) {
|
||||
/* Mitm server. */
|
||||
AMS_ABORT_UNLESS(this->CanManageMitmServers());
|
||||
os::SetMultiWaitHolderUserData(server, static_cast<uintptr_t>(UserDataTag::MitmServer));
|
||||
} else {
|
||||
/* Non-mitm server. */
|
||||
|
@ -148,6 +158,26 @@ namespace ams::sf::hipc {
|
|||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result InstallMitmServerImpl(os::NativeHandle *out_port_handle, sm::ServiceName service_name, MitmQueryFunction query_func);
|
||||
protected:
|
||||
virtual Server *AllocateServer() = 0;
|
||||
virtual void DestroyServer(Server *server) = 0;
|
||||
virtual Result OnNeedsToAccept(int port_index, Server *server) {
|
||||
AMS_UNUSED(port_index, server);
|
||||
AMS_ABORT("OnNeedsToAccept must be overridden when using indexed ports");
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
Result AcceptImpl(Server *server, SharedPointer<Interface> p) {
|
||||
return ServerSessionManager::AcceptSession(server->m_port_handle, std::move(p));
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
Result AcceptMitmImpl(Server *server, SharedPointer<Interface> p, std::shared_ptr<::Service> forward_service) {
|
||||
AMS_ABORT_UNLESS(this->CanManageMitmServers());
|
||||
return ServerSessionManager::AcceptMitmSession(server->m_port_handle, std::move(p), std::move(forward_service));
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
Result RegisterMitmServerImpl(int index, cmif::ServiceObjectHolder &&static_holder, sm::ServiceName service_name) {
|
||||
/* Install mitm service. */
|
||||
|
@ -170,30 +200,11 @@ namespace ams::sf::hipc {
|
|||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result InstallMitmServerImpl(os::NativeHandle *out_port_handle, sm::ServiceName service_name, MitmQueryFunction query_func);
|
||||
protected:
|
||||
virtual Server *AllocateServer() = 0;
|
||||
virtual void DestroyServer(Server *server) = 0;
|
||||
virtual Result OnNeedsToAccept(int port_index, Server *server) {
|
||||
AMS_UNUSED(port_index, server);
|
||||
AMS_ABORT("OnNeedsToAccept must be overridden when using indexed ports");
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
Result AcceptImpl(Server *server, SharedPointer<Interface> p) {
|
||||
return ServerSessionManager::AcceptSession(server->m_port_handle, std::move(p));
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
Result AcceptMitmImpl(Server *server, SharedPointer<Interface> p, std::shared_ptr<::Service> forward_service) {
|
||||
return ServerSessionManager::AcceptMitmSession(server->m_port_handle, std::move(p), std::move(forward_service));
|
||||
}
|
||||
public:
|
||||
ServerManagerBase(DomainEntryStorage *entry_storage, size_t entry_count) :
|
||||
ServerManagerBase(DomainEntryStorage *entry_storage, size_t entry_count, bool defer_supported, bool mitm_supported) :
|
||||
ServerDomainSessionManager(entry_storage, entry_count),
|
||||
m_request_stop_event(os::EventClearMode_ManualClear), m_notify_event(os::EventClearMode_ManualClear),
|
||||
m_selection_mutex(), m_deferred_list_mutex()
|
||||
m_selection_mutex(), m_deferred_list_mutex(), m_is_defer_supported(defer_supported), m_is_mitm_supported(mitm_supported)
|
||||
{
|
||||
/* Link multi-wait holders. */
|
||||
os::InitializeMultiWait(std::addressof(m_multi_wait));
|
||||
|
@ -205,6 +216,22 @@ namespace ams::sf::hipc {
|
|||
os::InitializeMultiWait(std::addressof(m_deferred_list));
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE bool CanAnyDeferInvokeRequest() {
|
||||
return g_is_any_deferred_supported;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE bool CanAnyManageMitmServers() {
|
||||
return g_is_any_mitm_supported;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool CanDeferInvokeRequest() const {
|
||||
return CanAnyDeferInvokeRequest() && m_is_defer_supported;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE bool CanManageMitmServers() const {
|
||||
return CanAnyManageMitmServers() && m_is_mitm_supported;
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
void RegisterObjectForServer(SharedPointer<Interface> static_object, os::NativeHandle port_handle) {
|
||||
this->RegisterServerImpl(0, cmif::ServiceObjectHolder(std::move(static_object)), port_handle, false);
|
||||
|
@ -223,11 +250,6 @@ namespace ams::sf::hipc {
|
|||
return this->RegisterServerImpl(port_index, cmif::ServiceObjectHolder(), service_name, max_sessions);
|
||||
}
|
||||
|
||||
template<typename Interface>
|
||||
Result RegisterMitmServer(int port_index, sm::ServiceName service_name) {
|
||||
return this->template RegisterMitmServerImpl<Interface>(port_index, cmif::ServiceObjectHolder(), service_name);
|
||||
}
|
||||
|
||||
/* Processing. */
|
||||
os::MultiWaitHolderType *WaitSignaled();
|
||||
|
||||
|
@ -267,7 +289,7 @@ namespace ams::sf::hipc {
|
|||
util::TypedStorage<ServerSession> m_session_storages[MaxSessions];
|
||||
bool m_session_allocated[MaxSessions];
|
||||
u8 m_pointer_buffer_storage[0x10 + (MaxSessions * ManagerOptions::PointerBufferSize)];
|
||||
u8 m_saved_message_storage[0x10 + (MaxSessions * hipc::TlsMessageBufferSize)];
|
||||
u8 m_saved_message_storage[0x10 + (MaxSessions * (ManagerOptions::CanDeferInvokeRequest ? hipc::TlsMessageBufferSize : 0))];
|
||||
uintptr_t m_pointer_buffers_start;
|
||||
uintptr_t m_saved_messages_start;
|
||||
|
||||
|
@ -337,12 +359,16 @@ namespace ams::sf::hipc {
|
|||
os::UnlinkMultiWaitHolder(server);
|
||||
os::FinalizeMultiWaitHolder(server);
|
||||
if (server->m_service_managed) {
|
||||
if (server->m_is_mitm_server) {
|
||||
R_ABORT_UNLESS(sm::mitm::UninstallMitm(server->m_service_name));
|
||||
if constexpr (ManagerOptions::CanManageMitmServers) {
|
||||
if (server->m_is_mitm_server) {
|
||||
R_ABORT_UNLESS(sm::mitm::UninstallMitm(server->m_service_name));
|
||||
} else {
|
||||
R_ABORT_UNLESS(sm::UnregisterService(server->m_service_name));
|
||||
}
|
||||
} else {
|
||||
R_ABORT_UNLESS(sm::UnregisterService(server->m_service_name));
|
||||
}
|
||||
R_ABORT_UNLESS(svc::CloseHandle(server->m_port_handle));
|
||||
os::CloseNativeHandle(server->m_port_handle);
|
||||
}
|
||||
}
|
||||
m_server_allocated[index] = false;
|
||||
|
@ -377,10 +403,14 @@ namespace ams::sf::hipc {
|
|||
}
|
||||
|
||||
virtual cmif::PointerAndSize GetSessionSavedMessageBuffer(const ServerSession *session) const override final {
|
||||
return this->GetObjectBySessionIndex(session, m_saved_messages_start, hipc::TlsMessageBufferSize);
|
||||
if constexpr (ManagerOptions::CanDeferInvokeRequest) {
|
||||
return this->GetObjectBySessionIndex(session, m_saved_messages_start, hipc::TlsMessageBufferSize);
|
||||
} else {
|
||||
return cmif::PointerAndSize();
|
||||
}
|
||||
}
|
||||
public:
|
||||
ServerManager() : ServerManagerBase(m_domain_entry_storages, ManagerOptions::MaxDomainObjects), m_resource_mutex() {
|
||||
ServerManager() : ServerManagerBase(m_domain_entry_storages, ManagerOptions::MaxDomainObjects, ManagerOptions::CanDeferInvokeRequest, ManagerOptions::CanManageMitmServers), m_resource_mutex() {
|
||||
/* Clear storages. */
|
||||
#define SF_SM_MEMCLEAR(obj) if constexpr (sizeof(obj) > 0) { std::memset(obj, 0, sizeof(obj)); }
|
||||
SF_SM_MEMCLEAR(m_server_storages);
|
||||
|
@ -395,6 +425,14 @@ namespace ams::sf::hipc {
|
|||
/* Set resource starts. */
|
||||
m_pointer_buffers_start = util::AlignUp(reinterpret_cast<uintptr_t>(m_pointer_buffer_storage), 0x10);
|
||||
m_saved_messages_start = util::AlignUp(reinterpret_cast<uintptr_t>(m_saved_message_storage), 0x10);
|
||||
|
||||
/* Update globals. */
|
||||
if constexpr (ManagerOptions::CanDeferInvokeRequest) {
|
||||
ServerManagerBase::g_is_any_deferred_supported = true;
|
||||
}
|
||||
if constexpr (ManagerOptions::CanManageMitmServers) {
|
||||
ServerManagerBase::g_is_any_mitm_supported = true;
|
||||
}
|
||||
}
|
||||
|
||||
~ServerManager() {
|
||||
|
@ -416,6 +454,12 @@ namespace ams::sf::hipc {
|
|||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
template<typename Interface, bool Enable = ManagerOptions::CanManageMitmServers, typename = typename std::enable_if<Enable>::type>
|
||||
Result RegisterMitmServer(int port_index, sm::ServiceName service_name) {
|
||||
AMS_ABORT_UNLESS(this->CanManageMitmServers());
|
||||
return this->template RegisterMitmServerImpl<Interface>(port_index, cmif::ServiceObjectHolder(), service_name);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -48,29 +48,29 @@ namespace ams::sf::hipc {
|
|||
cmif::ServiceObjectHolder m_srv_obj_holder;
|
||||
cmif::PointerAndSize m_pointer_buffer;
|
||||
cmif::PointerAndSize m_saved_message;
|
||||
std::shared_ptr<::Service> m_forward_service;
|
||||
util::TypedStorage<std::shared_ptr<::Service>> m_forward_service;
|
||||
os::NativeHandle m_session_handle;
|
||||
bool m_is_closed;
|
||||
bool m_has_received;
|
||||
const bool m_has_forward_service;
|
||||
public:
|
||||
ServerSession(os::NativeHandle h, cmif::ServiceObjectHolder &&obj) : m_srv_obj_holder(std::move(obj)), m_session_handle(h) {
|
||||
ServerSession(os::NativeHandle h, cmif::ServiceObjectHolder &&obj) : m_srv_obj_holder(std::move(obj)), m_session_handle(h), m_has_forward_service(false) {
|
||||
hipc::AttachMultiWaitHolderForReply(this, h);
|
||||
m_is_closed = false;
|
||||
m_has_received = false;
|
||||
m_forward_service = nullptr;
|
||||
AMS_ABORT_UNLESS(!this->IsMitmSession());
|
||||
}
|
||||
|
||||
ServerSession(os::NativeHandle h, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) : m_srv_obj_holder(std::move(obj)), m_session_handle(h) {
|
||||
ServerSession(os::NativeHandle h, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) : m_srv_obj_holder(std::move(obj)), m_session_handle(h), m_has_forward_service(true) {
|
||||
hipc::AttachMultiWaitHolderForReply(this, h);
|
||||
m_is_closed = false;
|
||||
m_has_received = false;
|
||||
m_forward_service = std::move(fsrv);
|
||||
AMS_ABORT_UNLESS(this->IsMitmSession());
|
||||
util::ConstructAt(m_forward_service, std::move(fsrv));
|
||||
AMS_ABORT_UNLESS(util::GetReference(m_forward_service) != nullptr);
|
||||
}
|
||||
|
||||
bool IsMitmSession() const {
|
||||
return m_forward_service != nullptr;
|
||||
ALWAYS_INLINE bool IsMitmSession() const {
|
||||
return m_has_forward_service;
|
||||
}
|
||||
|
||||
Result ForwardRequest(const cmif::ServiceDispatchContext &ctx) const;
|
||||
|
|
|
@ -27,9 +27,11 @@ namespace ams::erpt::srv {
|
|||
namespace {
|
||||
|
||||
struct ErrorReportServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0;
|
||||
static constexpr size_t MaxDomains = 64;
|
||||
static constexpr size_t MaxDomainObjects = 2 * ReportCountMax + 5 + 2;
|
||||
static constexpr size_t PointerBufferSize = 0;
|
||||
static constexpr size_t MaxDomains = 64;
|
||||
static constexpr size_t MaxDomainObjects = 2 * ReportCountMax + 5 + 2;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
constexpr inline size_t ErrorReportNumServers = 2;
|
||||
|
|
|
@ -26,9 +26,11 @@ namespace ams::htcfs {
|
|||
static constexpr inline sm::ServiceName ServiceName = sm::ServiceName::Encode("file_io");
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x1000;
|
||||
static constexpr size_t MaxDomains = 0x10;
|
||||
static constexpr size_t MaxDomainObjects = 0x100;
|
||||
static constexpr size_t PointerBufferSize = 0x1000;
|
||||
static constexpr size_t MaxDomains = 0x10;
|
||||
static constexpr size_t MaxDomainObjects = 0x100;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
using ServerManager = sf::hipc::ServerManager<NumServers, ServerOptions, MaxSessions>;
|
||||
|
|
|
@ -25,9 +25,11 @@ namespace ams::htcs::server {
|
|||
static constexpr inline sm::ServiceName ServiceName = sm::ServiceName::Encode("htcs");
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x80;
|
||||
static constexpr size_t MaxDomains = 0x10;
|
||||
static constexpr size_t MaxDomainObjects = 100;
|
||||
static constexpr size_t PointerBufferSize = 0x80;
|
||||
static constexpr size_t MaxDomains = 0x10;
|
||||
static constexpr size_t MaxDomainObjects = 100;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
using ServerManager = sf::hipc::ServerManager<NumServers, ServerOptions, MaxSessions>;
|
||||
|
|
|
@ -30,9 +30,11 @@ namespace ams::lm::srv {
|
|||
constexpr inline size_t PortCountMax = 2;
|
||||
|
||||
struct ServerManagerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x400;
|
||||
static constexpr size_t MaxDomains = 31;
|
||||
static constexpr size_t MaxDomainObjects = 61;
|
||||
static constexpr size_t PointerBufferSize = 0x400;
|
||||
static constexpr size_t MaxDomains = 31;
|
||||
static constexpr size_t MaxDomainObjects = 61;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
using ServerManager = sf::hipc::ServerManager<PortCountMax, ServerManagerOptions, SessionCountMax>;
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace ams::sf::hipc::impl {
|
|||
|
||||
class MitmQueryService {
|
||||
private:
|
||||
ServerManagerBase::MitmQueryFunction m_query_function;
|
||||
const ServerManagerBase::MitmQueryFunction m_query_function;
|
||||
public:
|
||||
MitmQueryService(ServerManagerBase::MitmQueryFunction qf) : m_query_function(qf) { /* ... */ }
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace ams::sf::hipc {
|
|||
private:
|
||||
ServerDomainSessionManager *m_manager;
|
||||
ServerSession *m_session;
|
||||
bool m_is_mitm_session;
|
||||
const bool m_is_mitm_session;
|
||||
private:
|
||||
Result CloneCurrentObjectImpl(sf::OutMoveHandle &out_client_handle, ServerSessionManager *tagged_manager) {
|
||||
/* Clone the object. */
|
||||
|
@ -47,9 +47,12 @@ namespace ams::sf::hipc {
|
|||
if (!m_is_mitm_session) {
|
||||
R_ABORT_UNLESS(tagged_manager->RegisterSession(server_handle, std::move(clone)));
|
||||
} else {
|
||||
/* Check that we can create a mitm session. */
|
||||
AMS_ABORT_UNLESS(ServerManagerBase::CanAnyManageMitmServers());
|
||||
|
||||
/* Clone the forward service. */
|
||||
std::shared_ptr<::Service> new_forward_service = std::move(ServerSession::CreateForwardService());
|
||||
R_ABORT_UNLESS(serviceClone(m_session->m_forward_service.get(), new_forward_service.get()));
|
||||
R_ABORT_UNLESS(serviceClone(util::GetReference(m_session->m_forward_service).get(), new_forward_service.get()));
|
||||
R_ABORT_UNLESS(tagged_manager->RegisterMitmSession(server_handle, std::move(clone), std::move(new_forward_service)));
|
||||
}
|
||||
|
||||
|
@ -58,7 +61,7 @@ namespace ams::sf::hipc {
|
|||
return ResultSuccess();
|
||||
}
|
||||
public:
|
||||
explicit HipcManagerImpl(ServerDomainSessionManager *m, ServerSession *s) : m_manager(m), m_session(s), m_is_mitm_session(s->m_forward_service != nullptr) {
|
||||
explicit HipcManagerImpl(ServerDomainSessionManager *m, ServerSession *s) : m_manager(m), m_session(s), m_is_mitm_session(s->IsMitmSession()) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
|
@ -70,15 +73,18 @@ namespace ams::sf::hipc {
|
|||
/* Set up the new domain object. */
|
||||
cmif::DomainObjectId object_id = cmif::InvalidDomainObjectId;
|
||||
if (m_is_mitm_session) {
|
||||
/* Check that we can create a mitm session. */
|
||||
AMS_ABORT_UNLESS(ServerManagerBase::CanAnyManageMitmServers());
|
||||
|
||||
/* Make a new shared pointer to manage the allocated domain. */
|
||||
SharedPointer<cmif::MitmDomainServiceObject> cmif_domain(static_cast<cmif::MitmDomainServiceObject *>(domain), false);
|
||||
|
||||
/* Convert the remote session to domain. */
|
||||
AMS_ABORT_UNLESS(m_session->m_forward_service->own_handle);
|
||||
R_TRY(serviceConvertToDomain(m_session->m_forward_service.get()));
|
||||
AMS_ABORT_UNLESS(util::GetReference(m_session->m_forward_service)->own_handle);
|
||||
R_TRY(serviceConvertToDomain(util::GetReference(m_session->m_forward_service).get()));
|
||||
|
||||
/* The object ID reservation cannot fail here, as that would cause desynchronization from target domain. */
|
||||
object_id = cmif::DomainObjectId{m_session->m_forward_service->object_id};
|
||||
object_id = cmif::DomainObjectId{util::GetReference(m_session->m_forward_service)->object_id};
|
||||
domain->ReserveSpecificIds(std::addressof(object_id), 1);
|
||||
|
||||
/* Register the object. */
|
||||
|
@ -116,14 +122,17 @@ namespace ams::sf::hipc {
|
|||
if (!object) {
|
||||
R_UNLESS(m_is_mitm_session, sf::hipc::ResultDomainObjectNotFound());
|
||||
|
||||
/* Check that we can create a mitm session. */
|
||||
AMS_ABORT_UNLESS(ServerManagerBase::CanAnyManageMitmServers());
|
||||
|
||||
os::NativeHandle handle;
|
||||
R_TRY(cmifCopyFromCurrentDomain(m_session->m_forward_service->session, object_id.value, std::addressof(handle)));
|
||||
R_TRY(cmifCopyFromCurrentDomain(util::GetReference(m_session->m_forward_service)->session, object_id.value, std::addressof(handle)));
|
||||
|
||||
out.SetValue(handle, false);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
if (!m_is_mitm_session || object_id.value != serviceGetObjectId(m_session->m_forward_service.get())) {
|
||||
if (!m_is_mitm_session || (ServerManagerBase::CanAnyManageMitmServers() && object_id.value != serviceGetObjectId(util::GetReference(m_session->m_forward_service).get()))) {
|
||||
/* Create new session handles. */
|
||||
os::NativeHandle server_handle, client_handle;
|
||||
R_ABORT_UNLESS(hipc::CreateSession(std::addressof(server_handle), std::addressof(client_handle)));
|
||||
|
@ -134,9 +143,12 @@ namespace ams::sf::hipc {
|
|||
/* Set output client handle. */
|
||||
out.SetValue(client_handle, false);
|
||||
} else {
|
||||
/* Check that we can create a mitm session. */
|
||||
AMS_ABORT_UNLESS(ServerManagerBase::CanAnyManageMitmServers());
|
||||
|
||||
/* Copy from the target domain. */
|
||||
os::NativeHandle new_forward_target;
|
||||
R_TRY(cmifCopyFromCurrentDomain(m_session->m_forward_service->session, object_id.value, std::addressof(new_forward_target)));
|
||||
R_TRY(cmifCopyFromCurrentDomain(util::GetReference(m_session->m_forward_service)->session, object_id.value, std::addressof(new_forward_target)));
|
||||
|
||||
/* Create new session handles. */
|
||||
os::NativeHandle server_handle, client_handle;
|
||||
|
|
|
@ -114,21 +114,34 @@ namespace ams::sf::hipc {
|
|||
ServerSession *session = static_cast<ServerSession *>(holder);
|
||||
|
||||
cmif::PointerAndSize tls_message(svc::GetThreadLocalRegion()->message_buffer, hipc::TlsMessageBufferSize);
|
||||
const cmif::PointerAndSize &saved_message = session->m_saved_message;
|
||||
AMS_ABORT_UNLESS(tls_message.GetSize() == saved_message.GetSize());
|
||||
if (!session->m_has_received) {
|
||||
R_TRY(this->ReceiveRequest(session, tls_message));
|
||||
session->m_has_received = true;
|
||||
std::memcpy(saved_message.GetPointer(), tls_message.GetPointer(), tls_message.GetSize());
|
||||
} else {
|
||||
/* We were deferred and are re-receiving, so just memcpy. */
|
||||
std::memcpy(tls_message.GetPointer(), saved_message.GetPointer(), tls_message.GetSize());
|
||||
}
|
||||
if (this->CanDeferInvokeRequest()) {
|
||||
const cmif::PointerAndSize &saved_message = session->m_saved_message;
|
||||
AMS_ABORT_UNLESS(tls_message.GetSize() == saved_message.GetSize());
|
||||
|
||||
/* Treat a meta "Context Invalidated" message as a success. */
|
||||
R_TRY_CATCH(this->ProcessRequest(session, tls_message)) {
|
||||
R_CONVERT(sf::impl::ResultRequestInvalidated, ResultSuccess());
|
||||
} R_END_TRY_CATCH;
|
||||
if (!session->m_has_received) {
|
||||
R_TRY(this->ReceiveRequest(session, tls_message));
|
||||
session->m_has_received = true;
|
||||
std::memcpy(saved_message.GetPointer(), tls_message.GetPointer(), tls_message.GetSize());
|
||||
} else {
|
||||
/* We were deferred and are re-receiving, so just memcpy. */
|
||||
std::memcpy(tls_message.GetPointer(), saved_message.GetPointer(), tls_message.GetSize());
|
||||
}
|
||||
|
||||
/* Treat a meta "Context Invalidated" message as a success. */
|
||||
R_TRY_CATCH(this->ProcessRequest(session, tls_message)) {
|
||||
R_CONVERT(sf::impl::ResultRequestInvalidated, ResultSuccess());
|
||||
} R_END_TRY_CATCH;
|
||||
} else {
|
||||
if (!session->m_has_received) {
|
||||
R_TRY(this->ReceiveRequest(session, tls_message));
|
||||
session->m_has_received = true;
|
||||
}
|
||||
|
||||
R_TRY_CATCH(this->ProcessRequest(session, tls_message)) {
|
||||
R_CATCH(sf::ResultRequestDeferred) { AMS_ABORT("Request Deferred on server which does not support deferral"); }
|
||||
R_CATCH(sf::impl::ResultRequestInvalidated) { AMS_ABORT("Request Invalidated on server which does not support deferral"); }
|
||||
} R_END_TRY_CATCH;
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -138,6 +151,7 @@ namespace ams::sf::hipc {
|
|||
case UserDataTag::Server:
|
||||
return this->ProcessForServer(holder);
|
||||
case UserDataTag::MitmServer:
|
||||
AMS_ABORT_UNLESS(this->CanManageMitmServers());
|
||||
return this->ProcessForMitmServer(holder);
|
||||
case UserDataTag::Session:
|
||||
return this->ProcessForSession(holder);
|
||||
|
|
|
@ -40,7 +40,9 @@ namespace ams::sf::hipc {
|
|||
}
|
||||
|
||||
Result ServerSession::ForwardRequest(const cmif::ServiceDispatchContext &ctx) const {
|
||||
AMS_ABORT_UNLESS(ServerManagerBase::CanAnyManageMitmServers());
|
||||
AMS_ABORT_UNLESS(this->IsMitmSession());
|
||||
|
||||
/* TODO: Support non-TLS messages? */
|
||||
AMS_ABORT_UNLESS(m_saved_message.GetPointer() != nullptr);
|
||||
AMS_ABORT_UNLESS(m_saved_message.GetSize() == TlsMessageBufferSize);
|
||||
|
@ -55,7 +57,7 @@ namespace ams::sf::hipc {
|
|||
PreProcessCommandBufferForMitm(ctx, m_pointer_buffer, reinterpret_cast<uintptr_t>(message_buffer));
|
||||
|
||||
/* Dispatch forwards. */
|
||||
R_TRY(svc::SendSyncRequest(m_forward_service->session));
|
||||
R_TRY(svc::SendSyncRequest(util::GetReference(m_forward_service)->session));
|
||||
|
||||
/* Parse, to ensure we catch any copy handles and close them. */
|
||||
{
|
||||
|
@ -114,6 +116,8 @@ namespace ams::sf::hipc {
|
|||
}
|
||||
|
||||
Result ServerSessionManager::RegisterMitmSessionImpl(ServerSession *session_memory, os::NativeHandle mitm_session_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) {
|
||||
AMS_ABORT_UNLESS(ServerManagerBase::CanAnyManageMitmServers());
|
||||
|
||||
/* Create session object. */
|
||||
std::construct_at(session_memory, mitm_session_handle, std::forward<cmif::ServiceObjectHolder>(obj), std::forward<std::shared_ptr<::Service>>(fsrv));
|
||||
|
||||
|
@ -122,8 +126,8 @@ namespace ams::sf::hipc {
|
|||
session_memory->m_saved_message = this->GetSessionSavedMessageBuffer(session_memory);
|
||||
|
||||
/* Validate session pointer buffer. */
|
||||
AMS_ABORT_UNLESS(session_memory->m_pointer_buffer.GetSize() >= session_memory->m_forward_service->pointer_buffer_size);
|
||||
session_memory->m_pointer_buffer = cmif::PointerAndSize(session_memory->m_pointer_buffer.GetAddress(), session_memory->m_forward_service->pointer_buffer_size);
|
||||
AMS_ABORT_UNLESS(session_memory->m_pointer_buffer.GetSize() >= util::GetReference(session_memory->m_forward_service)->pointer_buffer_size);
|
||||
session_memory->m_pointer_buffer = cmif::PointerAndSize(session_memory->m_pointer_buffer.GetAddress(), util::GetReference(session_memory->m_forward_service)->pointer_buffer_size);
|
||||
|
||||
/* Register to wait list. */
|
||||
this->RegisterServerSessionToWait(session_memory);
|
||||
|
@ -131,6 +135,8 @@ namespace ams::sf::hipc {
|
|||
}
|
||||
|
||||
Result ServerSessionManager::AcceptMitmSessionImpl(ServerSession *session_memory, os::NativeHandle mitm_port_handle, cmif::ServiceObjectHolder &&obj, std::shared_ptr<::Service> &&fsrv) {
|
||||
AMS_ABORT_UNLESS(ServerManagerBase::CanAnyManageMitmServers());
|
||||
|
||||
/* Create session handle. */
|
||||
os::NativeHandle mitm_session_handle;
|
||||
R_TRY(svc::AcceptSession(std::addressof(mitm_session_handle), mitm_port_handle));
|
||||
|
@ -201,7 +207,7 @@ namespace ams::sf::hipc {
|
|||
|
||||
namespace {
|
||||
|
||||
NX_CONSTEXPR u32 GetCmifCommandType(const cmif::PointerAndSize &message) {
|
||||
constexpr ALWAYS_INLINE u32 GetCmifCommandType(const cmif::PointerAndSize &message) {
|
||||
HipcHeader hdr = {};
|
||||
__builtin_memcpy(std::addressof(hdr), message.GetPointer(), sizeof(hdr));
|
||||
return hdr.type;
|
||||
|
|
|
@ -41,9 +41,11 @@ namespace ams::sprofile::srv {
|
|||
constexpr inline size_t PortCountMax = 2;
|
||||
|
||||
struct ServerManagerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x0;
|
||||
static constexpr size_t MaxDomains = SessionCountMax; /* NOTE: Official is 3 */
|
||||
static constexpr size_t MaxDomainObjects = 16; /* NOTE: Official is 8 */
|
||||
static constexpr size_t PointerBufferSize = 0x0;
|
||||
static constexpr size_t MaxDomains = SessionCountMax; /* NOTE: Official is 3 */
|
||||
static constexpr size_t MaxDomainObjects = 16; /* NOTE: Official is 8 */
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
using ServerManager = sf::hipc::ServerManager<PortCountMax, ServerManagerOptions, SessionCountMax>;
|
||||
|
|
|
@ -32,7 +32,14 @@ namespace ams::mitm::bpc {
|
|||
constexpr size_t MitmServiceMaxSessions = 13;
|
||||
|
||||
constexpr size_t MaxSessions = MitmServiceMaxSessions;
|
||||
using ServerOptions = sf::hipc::DefaultServerManagerOptions;
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = sf::hipc::DefaultServerManagerOptions::PointerBufferSize;
|
||||
static constexpr size_t MaxDomains = sf::hipc::DefaultServerManagerOptions::MaxDomains;
|
||||
static constexpr size_t MaxDomainObjects = sf::hipc::DefaultServerManagerOptions::MaxDomainObjects;
|
||||
static constexpr bool CanDeferInvokeRequest = sf::hipc::DefaultServerManagerOptions::CanDeferInvokeRequest;
|
||||
static constexpr bool CanManageMitmServers = true;
|
||||
};
|
||||
|
||||
class ServerManager final : public sf::hipc::ServerManager<PortIndex_Count, ServerOptions, MaxSessions> {
|
||||
private:
|
||||
|
|
|
@ -32,7 +32,14 @@ namespace ams::mitm::socket::resolver {
|
|||
constexpr sm::ServiceName DnsMitmServiceName = sm::ServiceName::Encode("sfdnsres");
|
||||
|
||||
constexpr size_t MaxSessions = 30;
|
||||
using ServerOptions = sf::hipc::DefaultServerManagerOptions;
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = sf::hipc::DefaultServerManagerOptions::PointerBufferSize;
|
||||
static constexpr size_t MaxDomains = sf::hipc::DefaultServerManagerOptions::MaxDomains;
|
||||
static constexpr size_t MaxDomainObjects = sf::hipc::DefaultServerManagerOptions::MaxDomainObjects;
|
||||
static constexpr bool CanDeferInvokeRequest = sf::hipc::DefaultServerManagerOptions::CanDeferInvokeRequest;
|
||||
static constexpr bool CanManageMitmServers = true;
|
||||
};
|
||||
|
||||
class ServerManager final : public sf::hipc::ServerManager<PortIndex_Count, ServerOptions, MaxSessions> {
|
||||
private:
|
||||
|
|
|
@ -29,9 +29,11 @@ namespace ams::mitm::fs {
|
|||
constexpr sm::ServiceName MitmServiceName = sm::ServiceName::Encode("fsp-srv");
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x800;
|
||||
static constexpr size_t MaxDomains = 0x40;
|
||||
static constexpr size_t MaxDomainObjects = 0x4000;
|
||||
static constexpr size_t PointerBufferSize = 0x800;
|
||||
static constexpr size_t MaxDomains = 0x40;
|
||||
static constexpr size_t MaxDomainObjects = 0x4000;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = true;
|
||||
};
|
||||
|
||||
constexpr size_t MaxSessions = 61;
|
||||
|
|
|
@ -32,7 +32,14 @@ namespace ams::mitm::ns {
|
|||
constexpr sm::ServiceName NsWebMitmServiceName = sm::ServiceName::Encode("ns:web");
|
||||
|
||||
constexpr size_t MaxSessions = 5;
|
||||
using ServerOptions = sf::hipc::DefaultServerManagerOptions;
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = sf::hipc::DefaultServerManagerOptions::PointerBufferSize;
|
||||
static constexpr size_t MaxDomains = sf::hipc::DefaultServerManagerOptions::MaxDomains;
|
||||
static constexpr size_t MaxDomainObjects = sf::hipc::DefaultServerManagerOptions::MaxDomainObjects;
|
||||
static constexpr bool CanDeferInvokeRequest = sf::hipc::DefaultServerManagerOptions::CanDeferInvokeRequest;
|
||||
static constexpr bool CanManageMitmServers = true;
|
||||
};
|
||||
|
||||
class ServerManager final : public sf::hipc::ServerManager<PortIndex_Count, ServerOptions, MaxSessions> {
|
||||
private:
|
||||
|
|
|
@ -33,9 +33,11 @@ namespace ams::mitm::settings {
|
|||
constexpr sm::ServiceName SetSysMitmServiceName = sm::ServiceName::Encode("set:sys");
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x200;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr size_t PointerBufferSize = 0x200;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = true;
|
||||
};
|
||||
|
||||
constexpr size_t MaxSessions = 60;
|
||||
|
|
|
@ -34,9 +34,11 @@ namespace ams::mitm::sysupdater {
|
|||
constexpr size_t MaxSessions = SystemUpdateMaxSessions + 3;
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 1_KB;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr size_t PointerBufferSize = 1_KB;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
sf::hipc::ServerManager<PortIndex_Count, ServerOptions, MaxSessions> g_server_manager;
|
||||
|
|
|
@ -46,9 +46,11 @@ namespace ams {
|
|||
namespace {
|
||||
|
||||
struct ServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x400;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr size_t PointerBufferSize = 0x400;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
/* ldr:pm, ldr:shel, ldr:dmnt. */
|
||||
|
|
|
@ -45,9 +45,11 @@ namespace ams {
|
|||
namespace {
|
||||
|
||||
struct ContentManagerServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x400;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr size_t PointerBufferSize = 0x400;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
constexpr inline size_t ContentManagerNumServers = 1;
|
||||
|
@ -90,9 +92,11 @@ namespace ams {
|
|||
};
|
||||
|
||||
struct LocationResolverServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x400;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr size_t PointerBufferSize = 0x400;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
constexpr inline size_t LocationResolverNumServers = 1;
|
||||
|
|
|
@ -32,9 +32,11 @@ namespace ams {
|
|||
namespace {
|
||||
|
||||
struct SplServerOptions {
|
||||
static constexpr size_t PointerBufferSize = 0x800;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr size_t PointerBufferSize = 0x800;
|
||||
static constexpr size_t MaxDomains = 0;
|
||||
static constexpr size_t MaxDomainObjects = 0;
|
||||
static constexpr bool CanDeferInvokeRequest = false;
|
||||
static constexpr bool CanManageMitmServers = false;
|
||||
};
|
||||
|
||||
enum PortIndex {
|
||||
|
|
Loading…
Reference in a new issue