mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-09 22:56:35 +00:00
sm: fix deadlock semantics surrounding mitm installation
This commit is contained in:
parent
fac502aaa3
commit
99b5458539
10 changed files with 62 additions and 3 deletions
|
@ -32,6 +32,7 @@ namespace ams::sm::impl {
|
||||||
AMS_SF_METHOD_INFO(C, H, 65004, Result, AtmosphereHasMitm, (sf::Out<bool> out, ServiceName service)) \
|
AMS_SF_METHOD_INFO(C, H, 65004, Result, AtmosphereHasMitm, (sf::Out<bool> out, ServiceName service)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 65005, Result, AtmosphereWaitMitm, (ServiceName service)) \
|
AMS_SF_METHOD_INFO(C, H, 65005, Result, AtmosphereWaitMitm, (ServiceName service)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 65006, Result, AtmosphereDeclareFutureMitm, (ServiceName service)) \
|
AMS_SF_METHOD_INFO(C, H, 65006, Result, AtmosphereDeclareFutureMitm, (ServiceName service)) \
|
||||||
|
AMS_SF_METHOD_INFO(C, H, 65007, Result, AtmosphereClearFutureMitm, (ServiceName service)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 65100, Result, AtmosphereHasService, (sf::Out<bool> out, ServiceName service)) \
|
AMS_SF_METHOD_INFO(C, H, 65100, Result, AtmosphereHasService, (sf::Out<bool> out, ServiceName service)) \
|
||||||
AMS_SF_METHOD_INFO(C, H, 65101, Result, AtmosphereWaitService, (ServiceName service))
|
AMS_SF_METHOD_INFO(C, H, 65101, Result, AtmosphereWaitService, (ServiceName service))
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace ams::sm::mitm {
|
||||||
Result InstallMitm(Handle *out_port, Handle *out_query, ServiceName name);
|
Result InstallMitm(Handle *out_port, Handle *out_query, ServiceName name);
|
||||||
Result UninstallMitm(ServiceName name);
|
Result UninstallMitm(ServiceName name);
|
||||||
Result DeclareFutureMitm(ServiceName name);
|
Result DeclareFutureMitm(ServiceName name);
|
||||||
|
Result ClearFutureMitm(ServiceName name);
|
||||||
Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name);
|
Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name);
|
||||||
Result HasMitm(bool *out, ServiceName name);
|
Result HasMitm(bool *out, ServiceName name);
|
||||||
Result WaitMitm(ServiceName name);
|
Result WaitMitm(ServiceName name);
|
||||||
|
|
|
@ -27,6 +27,10 @@ namespace ams::sf::hipc {
|
||||||
|
|
||||||
/* Register the query handle. */
|
/* Register the query handle. */
|
||||||
impl::RegisterMitmQueryHandle(query_handle, query_func);
|
impl::RegisterMitmQueryHandle(query_handle, query_func);
|
||||||
|
|
||||||
|
/* Clear future declarations if any, now that our query handler is present. */
|
||||||
|
R_ABORT_UNLESS(sm::mitm::ClearFutureMitm(service_name));
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,10 @@ Result smAtmosphereMitmDeclareFuture(SmServiceName name) {
|
||||||
return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65006);
|
return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65006);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result smAtmosphereMitmClearFuture(SmServiceName name) {
|
||||||
|
return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65007);
|
||||||
|
}
|
||||||
|
|
||||||
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, void *_out, SmServiceName name) {
|
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, void *_out, SmServiceName name) {
|
||||||
struct {
|
struct {
|
||||||
u64 process_id;
|
u64 process_id;
|
||||||
|
|
|
@ -26,6 +26,7 @@ void smAtmosphereCloseSession(Service *srv);
|
||||||
Result smAtmosphereMitmInstall(Service *fwd_srv, Handle *handle_out, Handle *query_out, SmServiceName name);
|
Result smAtmosphereMitmInstall(Service *fwd_srv, Handle *handle_out, Handle *query_out, SmServiceName name);
|
||||||
Result smAtmosphereMitmUninstall(SmServiceName name);
|
Result smAtmosphereMitmUninstall(SmServiceName name);
|
||||||
Result smAtmosphereMitmDeclareFuture(SmServiceName name);
|
Result smAtmosphereMitmDeclareFuture(SmServiceName name);
|
||||||
|
Result smAtmosphereMitmClearFuture(SmServiceName name);
|
||||||
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, void *info_out, SmServiceName name);
|
Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, void *info_out, SmServiceName name);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -37,6 +37,12 @@ namespace ams::sm::mitm {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ClearFutureMitm(ServiceName name) {
|
||||||
|
return impl::DoWithUserSession([&]() {
|
||||||
|
return smAtmosphereMitmClearFuture(impl::ConvertName(name));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name) {
|
Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name) {
|
||||||
return impl::DoWithMitmAcknowledgementSession([&]() {
|
return impl::DoWithMitmAcknowledgementSession([&]() {
|
||||||
return smAtmosphereMitmAcknowledgeSession(out_service, reinterpret_cast<void *>(out_info), impl::ConvertName(name));
|
return smAtmosphereMitmAcknowledgeSession(out_service, reinterpret_cast<void *>(out_info), impl::ConvertName(name));
|
||||||
|
|
|
@ -588,6 +588,15 @@ namespace ams::sm::impl {
|
||||||
*out = INVALID_HANDLE;
|
*out = INVALID_HANDLE;
|
||||||
*out_query = INVALID_HANDLE;
|
*out_query = INVALID_HANDLE;
|
||||||
|
|
||||||
|
/* If we don't have a future mitm declaration, add one. */
|
||||||
|
/* Client will clear this when ready to process. */
|
||||||
|
bool has_existing_future_declaration = HasFutureMitmDeclaration(service);
|
||||||
|
if (!has_existing_future_declaration) {
|
||||||
|
R_TRY(AddFutureMitmDeclaration(service));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto future_guard = SCOPE_GUARD { if (!has_existing_future_declaration) { ClearFutureMitmDeclaration(service); } };
|
||||||
|
|
||||||
/* Create mitm handles. */
|
/* Create mitm handles. */
|
||||||
{
|
{
|
||||||
os::ManagedHandle hnd, port_hnd, qry_hnd, mitm_qry_hnd;
|
os::ManagedHandle hnd, port_hnd, qry_hnd, mitm_qry_hnd;
|
||||||
|
@ -603,9 +612,7 @@ namespace ams::sm::impl {
|
||||||
*out_query = qry_hnd.Move();
|
*out_query = qry_hnd.Move();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the future declaration, if one exists. */
|
future_guard.Cancel();
|
||||||
ClearFutureMitmDeclaration(service);
|
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,6 +658,34 @@ namespace ams::sm::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ClearFutureMitm(os::ProcessId process_id, ServiceName service) {
|
||||||
|
/* Validate service name. */
|
||||||
|
R_TRY(ValidateServiceName(service));
|
||||||
|
|
||||||
|
/* Check that the process is registered and allowed to register the service. */
|
||||||
|
if (!IsInitialProcess(process_id)) {
|
||||||
|
ProcessInfo *proc = GetProcessInfo(process_id);
|
||||||
|
R_UNLESS(proc != nullptr, sm::ResultInvalidClient());
|
||||||
|
R_TRY(ValidateAccessControl(AccessControlEntry(proc->access_control, proc->access_control_size), service, true, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that a future mitm declaration is present or we have a mitm. */
|
||||||
|
if (HasMitm(service)) {
|
||||||
|
/* Validate that the service exists. */
|
||||||
|
ServiceInfo *service_info = GetServiceInfo(service);
|
||||||
|
R_UNLESS(service_info != nullptr, sm::ResultNotRegistered());
|
||||||
|
|
||||||
|
/* Validate that the client process_id is the mitm process. */
|
||||||
|
R_UNLESS(service_info->mitm_process_id == process_id, sm::ResultNotAllowed());
|
||||||
|
} else {
|
||||||
|
R_UNLESS(HasFutureMitmDeclaration(service), sm::ResultNotRegistered());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the forward declaration. */
|
||||||
|
ClearFutureMitmDeclaration(service);
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
Result AcknowledgeMitmSession(MitmProcessInfo *out_info, Handle *out_hnd, os::ProcessId process_id, ServiceName service) {
|
Result AcknowledgeMitmSession(MitmProcessInfo *out_info, Handle *out_hnd, os::ProcessId process_id, ServiceName service) {
|
||||||
/* Validate service name. */
|
/* Validate service name. */
|
||||||
R_TRY(ValidateServiceName(service));
|
R_TRY(ValidateServiceName(service));
|
||||||
|
|
|
@ -37,6 +37,7 @@ namespace ams::sm::impl {
|
||||||
Result InstallMitm(Handle *out, Handle *out_query, os::ProcessId process_id, ServiceName service);
|
Result InstallMitm(Handle *out, Handle *out_query, os::ProcessId process_id, ServiceName service);
|
||||||
Result UninstallMitm(os::ProcessId process_id, ServiceName service);
|
Result UninstallMitm(os::ProcessId process_id, ServiceName service);
|
||||||
Result DeclareFutureMitm(os::ProcessId process_id, ServiceName service);
|
Result DeclareFutureMitm(os::ProcessId process_id, ServiceName service);
|
||||||
|
Result ClearFutureMitm(os::ProcessId process_id, ServiceName service);
|
||||||
Result AcknowledgeMitmSession(MitmProcessInfo *out_info, Handle *out_hnd, os::ProcessId process_id, ServiceName service);
|
Result AcknowledgeMitmSession(MitmProcessInfo *out_info, Handle *out_hnd, os::ProcessId process_id, ServiceName service);
|
||||||
|
|
||||||
/* Dmnt record extensions. */
|
/* Dmnt record extensions. */
|
||||||
|
|
|
@ -75,6 +75,11 @@ namespace ams::sm {
|
||||||
return impl::DeclareFutureMitm(this->process_id, service);
|
return impl::DeclareFutureMitm(this->process_id, service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result UserService::AtmosphereClearFutureMitm(ServiceName service) {
|
||||||
|
R_TRY(this->EnsureInitialized());
|
||||||
|
return impl::ClearFutureMitm(this->process_id, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Result UserService::AtmosphereHasService(sf::Out<bool> out, ServiceName service) {
|
Result UserService::AtmosphereHasService(sf::Out<bool> out, ServiceName service) {
|
||||||
R_TRY(this->EnsureInitialized());
|
R_TRY(this->EnsureInitialized());
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace ams::sm {
|
||||||
Result AtmosphereHasMitm(sf::Out<bool> out, ServiceName service);
|
Result AtmosphereHasMitm(sf::Out<bool> out, ServiceName service);
|
||||||
Result AtmosphereWaitMitm(ServiceName service);
|
Result AtmosphereWaitMitm(ServiceName service);
|
||||||
Result AtmosphereDeclareFutureMitm(ServiceName service);
|
Result AtmosphereDeclareFutureMitm(ServiceName service);
|
||||||
|
Result AtmosphereClearFutureMitm(ServiceName service);
|
||||||
|
|
||||||
Result AtmosphereHasService(sf::Out<bool> out, ServiceName service);
|
Result AtmosphereHasService(sf::Out<bool> out, ServiceName service);
|
||||||
Result AtmosphereWaitService(ServiceName service);
|
Result AtmosphereWaitService(ServiceName service);
|
||||||
|
|
Loading…
Reference in a new issue