pm: inform sm of title ids. remove inconsistent mitm association.

This commit is contained in:
Michael Scire 2019-07-03 22:57:49 -07:00 committed by SciresM
parent 4db212ea7b
commit 6777dd9b38
19 changed files with 150 additions and 97 deletions

View file

@ -16,6 +16,8 @@
#include <switch.h>
#include <stratosphere.hpp>
#include <stratosphere/cfg.hpp>
#include <stratosphere/ncm.hpp>
#include <stratosphere/sm.hpp>
#include "sm_service_manager.hpp"
@ -32,6 +34,7 @@ namespace sts::sm::impl {
/* Types. */
struct ProcessInfo {
u64 pid;
ncm::TitleId tid;
size_t access_control_size;
u8 access_control[AccessControlSizeMax];
@ -41,11 +44,15 @@ namespace sts::sm::impl {
void Free() {
this->pid = InvalidProcessId;
this->tid = ncm::TitleId::Invalid;
this->access_control_size = 0;
std::memset(this->access_control, 0, sizeof(this->access_control));
}
};
/* Forward declaration, for use in ServiceInfo. */
ncm::TitleId GetTitleIdForMitm(u64 pid);
struct ServiceInfo {
ServiceName name;
u64 owner_pid;
@ -95,9 +102,10 @@ namespace sts::sm::impl {
this->mitm_pid = InvalidProcessId;
}
void AcknowledgeMitmSession(u64 *out_pid, Handle *out_hnd) {
void AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd) {
/* Copy to output. */
*out_pid = this->mitm_waiting_ack_pid;
*out_tid = GetTitleIdForMitm(this->mitm_waiting_ack_pid);
*out_hnd = this->mitm_fwd_sess_h.Move();
this->mitm_waiting_ack = false;
this->mitm_waiting_ack_pid = InvalidProcessId;
@ -149,27 +157,13 @@ namespace sts::sm::impl {
};
class InitialProcessIdLimits {
public:
static constexpr u64 InitialProcessIdMin = 0x00;
static constexpr u64 InitialProcessIdMax = 0x50;
private:
u64 min;
u64 max;
public:
InitialProcessIdLimits() {
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_500) {
/* On 5.0.0+, we can get precise limits from svcGetSystemInfo. */
R_ASSERT(svcGetSystemInfo(&this->min, SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum));
R_ASSERT(svcGetSystemInfo(&this->max, SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum));
} else if (GetRuntimeFirmwareVersion() >= FirmwareVersion_400) {
/* On 4.0.0-4.1.0, we can get the precise limits from normal svcGetInfo. */
R_ASSERT(svcGetInfo(&this->min, InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum));
R_ASSERT(svcGetInfo(&this->max, InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum));
} else {
/* On < 4.0.0, we just use hardcoded extents. */
this->min = InitialProcessIdMin;
this->max = InitialProcessIdMax;
}
/* Retrieve process limits. */
cfg::GetInitialProcessRange(&this->min, &this->max);
/* Ensure range is sane. */
if (this->min > this->max) {
@ -301,6 +295,15 @@ namespace sts::sm::impl {
return pid != InvalidProcessId;
}
ncm::TitleId GetTitleIdForMitm(u64 pid) {
/* Anything that can request a mitm session must have a process info. */
const auto process_info = GetProcessInfo(pid);
if (process_info == nullptr) {
std::abort();
}
return process_info->tid;
}
bool ShouldDeferForInit(ServiceName service) {
/* Once end has been called, we're done. */
if (g_ended_initial_defers) {
@ -321,10 +324,12 @@ namespace sts::sm::impl {
u64 magic;
u64 cmd_id;
u64 pid;
ncm::TitleId tid;
} *info = ((decltype(info))ipcPrepareHeader(&c, sizeof(*info)));
info->magic = SFCI_MAGIC;
info->cmd_id = 65000;
info->pid = pid;
info->tid = GetTitleIdForMitm(pid);
R_TRY(ipcDispatch(service_info->mitm_query_h.Get()));
}
@ -414,9 +419,9 @@ namespace sts::sm::impl {
}
/* Process management. */
Result RegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size) {
Result RegisterProcess(u64 pid, ncm::TitleId tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size) {
/* Check that access control will fit in the ServiceInfo. */
if (aci0_sac_size > AccessControlSizeMax) {
if (aci_sac_size > AccessControlSizeMax) {
return ResultSmTooLargeAccessControl;
}
@ -427,15 +432,16 @@ namespace sts::sm::impl {
}
/* Validate restrictions. */
if (!aci0_sac_size) {
if (!aci_sac_size) {
return ResultSmNotAllowed;
}
R_TRY(ValidateAccessControl(AccessControlEntry(acid_sac, acid_sac_size), AccessControlEntry(aci0_sac, aci0_sac_size)));
R_TRY(ValidateAccessControl(AccessControlEntry(acid_sac, acid_sac_size), AccessControlEntry(aci_sac, aci_sac_size)));
/* Save info. */
proc->pid = pid;
proc->access_control_size = aci0_sac_size;
std::memcpy(proc->access_control, aci0_sac, proc->access_control_size);
proc->tid = tid;
proc->access_control_size = aci_sac_size;
std::memcpy(proc->access_control, aci_sac, proc->access_control_size);
return ResultSuccess;
}
@ -662,7 +668,7 @@ namespace sts::sm::impl {
return ResultSuccess;
}
Result AcknowledgeMitmSession(u64 *out_pid, Handle *out_hnd, u64 pid, ServiceName service) {
Result AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, u64 pid, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
@ -686,30 +692,7 @@ namespace sts::sm::impl {
}
/* Acknowledge. */
service_info->AcknowledgeMitmSession(out_pid, out_hnd);
return ResultSuccess;
}
Result AssociatePidTidForMitm(u64 pid, u64 tid) {
for (size_t i = 0; i < ServiceCountMax; i++) {
const ServiceInfo *service_info = &g_service_list[i];
if (IsValidProcessId(service_info->mitm_pid)) {
/* Send association command to all mitm processes. */
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u64 pid;
u64 tid;
} *info = ((decltype(info))ipcPrepareHeader(&c, sizeof(*info)));
info->magic = SFCI_MAGIC;
info->cmd_id = 65001;
info->pid = pid;
info->tid = tid;
ipcDispatch(service_info->mitm_query_h.Get());
}
}
service_info->AcknowledgeMitmSession(out_pid, out_tid, out_hnd);
return ResultSuccess;
}

View file

@ -17,11 +17,12 @@
#pragma once
#include <switch.h>
#include <stratosphere/sm.hpp>
#include <stratosphere/ncm.hpp>
namespace sts::sm::impl {
/* Process management. */
Result RegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size);
Result RegisterProcess(u64 pid, ncm::TitleId tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size);
Result UnregisterProcess(u64 pid);
/* Service management. */
@ -37,8 +38,7 @@ namespace sts::sm::impl {
Result WaitMitm(ServiceName service);
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service);
Result UninstallMitm(u64 pid, ServiceName service);
Result AcknowledgeMitmSession(u64 *out_pid, Handle *out_hnd, u64 pid, ServiceName service);
Result AssociatePidTidForMitm(u64 pid, u64 tid);
Result AcknowledgeMitmSession(u64 *out_pid, ncm::TitleId *out_tid, Handle *out_hnd, u64 pid, ServiceName service);
/* Dmnt record extensions. */
Result GetServiceRecord(ServiceRecord *out, ServiceName service);

View file

@ -22,8 +22,8 @@
namespace sts::sm {
Result ManagerService::RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac) {
return impl::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements);
Result ManagerService::RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac) {
return impl::RegisterProcess(pid, ncm::TitleId::Invalid, acid_sac.buffer, acid_sac.num_elements, aci_sac.buffer, aci_sac.num_elements);
}
Result ManagerService::UnregisterProcess(u64 pid) {
@ -38,4 +38,9 @@ namespace sts::sm {
R_ASSERT(impl::HasMitm(out.GetPointer(), service));
}
Result ManagerService::AtmosphereRegisterProcess(u64 pid, ncm::TitleId tid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac) {
/* This takes in a title id, unlike RegisterProcess. */
return impl::RegisterProcess(pid, tid, acid_sac.buffer, acid_sac.num_elements, aci_sac.buffer, aci_sac.num_elements);
}
}

View file

@ -18,6 +18,7 @@
#include <switch.h>
#include <stratosphere.hpp>
#include <stratosphere/sm.hpp>
#include <stratosphere/ncm.hpp>
namespace sts::sm {
@ -26,18 +27,20 @@ namespace sts::sm {
protected:
/* Command IDs. */
enum class CommandId {
RegisterProcess = 0,
UnregisterProcess = 1,
RegisterProcess = 0,
UnregisterProcess = 1,
AtmosphereEndInitDefers = 65000,
AtmosphereHasMitm = 65001,
AtmosphereEndInitDefers = 65000,
AtmosphereHasMitm = 65001,
AtmosphereRegisterProcess = 65002,
};
private:
/* Actual commands. */
virtual Result RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac);
virtual Result RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac);
virtual Result UnregisterProcess(u64 pid);
virtual void AtmosphereEndInitDefers();
virtual void AtmosphereHasMitm(Out<bool> out, ServiceName service);
virtual Result AtmosphereRegisterProcess(u64 pid, ncm::TitleId tid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MAKE_SERVICE_COMMAND_META(ManagerService, RegisterProcess),
@ -45,6 +48,7 @@ namespace sts::sm {
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereEndInitDefers),
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereHasMitm),
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereRegisterProcess),
};
};

View file

@ -60,14 +60,9 @@ namespace sts::sm {
return impl::UninstallMitm(this->pid, service);
}
Result UserService::AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service) {
Result UserService::AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<ncm::TitleId> client_tid, Out<MovedHandle> fwd_h, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
}
Result UserService::AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid) {
R_TRY(this->EnsureInitialized());
return impl::AssociatePidTidForMitm(pid, tid);
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), client_tid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
}
Result UserService::AtmosphereHasMitm(Out<bool> out, ServiceName service) {

View file

@ -18,6 +18,7 @@
#include <switch.h>
#include <stratosphere.hpp>
#include <stratosphere/sm.hpp>
#include <stratosphere/ncm.hpp>
namespace sts::sm {
@ -33,7 +34,7 @@ namespace sts::sm {
AtmosphereInstallMitm = 65000,
AtmosphereUninstallMitm = 65001,
AtmosphereAssociatePidTidForMitm = 65002,
/* Deprecated: AtmosphereAssociatePidTidForMitm = 65002 */
AtmosphereAcknowledgeMitmSession = 65003,
AtmosphereHasMitm = 65004,
AtmosphereWaitMitm = 65005,
@ -56,8 +57,7 @@ namespace sts::sm {
/* Atmosphere commands. */
virtual Result AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, ServiceName service);
virtual Result AtmosphereUninstallMitm(ServiceName service);
virtual Result AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid);
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service);
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<ncm::TitleId> client_tid, Out<MovedHandle> fwd_h, ServiceName service);
virtual Result AtmosphereHasMitm(Out<bool> out, ServiceName service);
virtual Result AtmosphereWaitMitm(ServiceName service);
@ -72,7 +72,6 @@ namespace sts::sm {
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereInstallMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereUninstallMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAssociatePidTidForMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAcknowledgeMitmSession),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasMitm),
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereWaitMitm),