mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-12 07:44:52 +00:00
pm: inform sm of title ids. remove inconsistent mitm association.
This commit is contained in:
parent
4db212ea7b
commit
6777dd9b38
19 changed files with 150 additions and 97 deletions
|
@ -27,7 +27,7 @@ class BpcMitmService : public IMitmServiceObject {
|
||||||
RebootSystem = 1,
|
RebootSystem = 1,
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
BpcMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
BpcMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,12 +73,6 @@ void FsMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx
|
||||||
case CommandId::SetCurrentProcess:
|
case CommandId::SetCurrentProcess:
|
||||||
if (R_SUCCEEDED(ctx->rc)) {
|
if (R_SUCCEEDED(ctx->rc)) {
|
||||||
this_ptr->has_initialized = true;
|
this_ptr->has_initialized = true;
|
||||||
this_ptr->process_id = ctx->request.Pid;
|
|
||||||
this_ptr->title_id = sts::ncm::TitleId{this_ptr->process_id};
|
|
||||||
if (R_FAILED(MitmQueryUtils::GetAssociatedTidForPid(this_ptr->process_id, &this_ptr->title_id))) {
|
|
||||||
/* Log here, if desired. */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -44,7 +44,7 @@ class FsMitmService : public IMitmServiceObject {
|
||||||
bool has_initialized = false;
|
bool has_initialized = false;
|
||||||
bool should_override_contents;
|
bool should_override_contents;
|
||||||
public:
|
public:
|
||||||
FsMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
FsMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||||
if (Utils::HasSdDisableMitMFlag(static_cast<u64>(this->title_id))) {
|
if (Utils::HasSdDisableMitMFlag(static_cast<u64>(this->title_id))) {
|
||||||
this->should_override_contents = false;
|
this->should_override_contents = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -28,7 +28,7 @@ class NsAmMitmService : public IMitmServiceObject {
|
||||||
GetRunningApplicationProgramId = 92,
|
GetRunningApplicationProgramId = 92,
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
NsAmMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
NsAmMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ class NsWebMitmService : public IMitmServiceObject {
|
||||||
GetDocumentInterface = 7999,
|
GetDocumentInterface = 7999,
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
NsWebMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
NsWebMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ class SetMitmService : public IMitmServiceObject {
|
||||||
OverrideLocale locale;
|
OverrideLocale locale;
|
||||||
bool got_locale;
|
bool got_locale;
|
||||||
public:
|
public:
|
||||||
SetMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
SetMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||||
this->got_locale = false;
|
this->got_locale = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class SetSysMitmService : public IMitmServiceObject {
|
||||||
GetEdid = 41,
|
GetEdid = 41,
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
SetSysMitmService(std::shared_ptr<Service> s, u64 pid) : IMitmServiceObject(s, pid) {
|
SetSysMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||||
/* ... */
|
/* ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit ccfadc501bb89c3b42b7b4ed473094fee8c1043f
|
Subproject commit b9e53052732699e1f7af8ad061181e3798c3f8fc
|
|
@ -686,9 +686,6 @@ namespace sts::ldr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inform SM about the title for association purposes. */
|
|
||||||
R_ASSERT(sm::mitm::AssociateProcessIdAndTitleId(process_id, static_cast<u64>(loc.title_id)));
|
|
||||||
|
|
||||||
/* If we're overriding for HBL, perform HTML document redirection. */
|
/* If we're overriding for HBL, perform HTML document redirection. */
|
||||||
if (mount.IsHblMounted()) {
|
if (mount.IsHblMounted()) {
|
||||||
/* Don't validate result, failure is okay. */
|
/* Don't validate result, failure is okay. */
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||||
"svcCreateEvent": "0x45",
|
"svcCreateEvent": "0x45",
|
||||||
"svcSetUnsafeLimit": "0x4a",
|
"svcSetUnsafeLimit": "0x4a",
|
||||||
|
"svcDebugActiveProcess": "0x60",
|
||||||
|
"svcGetDebugEvent": "0x63",
|
||||||
"svcGetProcessList": "0x65",
|
"svcGetProcessList": "0x65",
|
||||||
"svcStartProcess": "0x7a",
|
"svcStartProcess": "0x7a",
|
||||||
"svcTerminateProcess": "0x7b",
|
"svcTerminateProcess": "0x7b",
|
||||||
|
@ -74,6 +76,13 @@
|
||||||
"svcGetSystemInfo": "0x6f",
|
"svcGetSystemInfo": "0x6f",
|
||||||
"svcCallSecureMonitor": "0x7F"
|
"svcCallSecureMonitor": "0x7F"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "debug_flags",
|
||||||
|
"value": {
|
||||||
|
"allow_debug": false,
|
||||||
|
"force_debug": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -245,12 +245,6 @@ namespace sts::boot2 {
|
||||||
cfg::WaitSdCardInitialized();
|
cfg::WaitSdCardInitialized();
|
||||||
R_ASSERT(fsdevMountSdmc());
|
R_ASSERT(fsdevMountSdmc());
|
||||||
|
|
||||||
/* Find out whether we are maintenance mode. */
|
|
||||||
const bool maintenance = IsMaintenanceMode();
|
|
||||||
if (maintenance) {
|
|
||||||
pm::bm::SetMaintenanceBoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for other atmosphere mitm modules to initialize. */
|
/* Wait for other atmosphere mitm modules to initialize. */
|
||||||
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("set:sys")));
|
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("set:sys")));
|
||||||
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200) {
|
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_200) {
|
||||||
|
@ -259,16 +253,26 @@ namespace sts::boot2 {
|
||||||
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc:c")));
|
R_ASSERT(sm::mitm::WaitMitm(sm::ServiceName::Encode("bpc:c")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find out whether we are maintenance mode. */
|
||||||
|
const bool maintenance = IsMaintenanceMode();
|
||||||
|
if (maintenance) {
|
||||||
|
pm::bm::SetMaintenanceBoot();
|
||||||
|
}
|
||||||
/* Launch Atmosphere dmnt, using FsStorageId_None to force SD card boot. */
|
/* Launch Atmosphere dmnt, using FsStorageId_None to force SD card boot. */
|
||||||
LaunchTitle(nullptr, ncm::TitleLocation::Make(ncm::TitleId::Dmnt, ncm::StorageId::None), 0);
|
LaunchTitle(nullptr, ncm::TitleLocation::Make(ncm::TitleId::Dmnt, ncm::StorageId::None), 0);
|
||||||
|
|
||||||
/* Launch additional programs. */
|
/* Launch additional programs. */
|
||||||
if (maintenance) {
|
if (maintenance) {
|
||||||
LaunchList(AdditionalMaintenanceLaunchPrograms, NumAdditionalMaintenanceLaunchPrograms);
|
LaunchList(AdditionalMaintenanceLaunchPrograms, NumAdditionalMaintenanceLaunchPrograms);
|
||||||
|
/* Starting in 7.0.0, npns is launched during maintenance boot. */
|
||||||
|
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_700) {
|
||||||
|
LaunchTitle(nullptr, ncm::TitleLocation::Make(ncm::TitleId::Npns, ncm::StorageId::NandSystem), 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LaunchList(AdditionalLaunchPrograms, NumAdditionalLaunchPrograms);
|
LaunchList(AdditionalLaunchPrograms, NumAdditionalLaunchPrograms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Launch user programs off of the SD. */
|
/* Launch user programs off of the SD. */
|
||||||
LaunchFlaggedProgramsFromSdCard();
|
LaunchFlaggedProgramsFromSdCard();
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ namespace sts::pm::impl {
|
||||||
|
|
||||||
/* Register with FS and SM. */
|
/* Register with FS and SM. */
|
||||||
R_TRY(fsprRegisterProgram(process_id, static_cast<u64>(location.title_id), static_cast<FsStorageId>(location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size));
|
R_TRY(fsprRegisterProgram(process_id, static_cast<u64>(location.title_id), static_cast<FsStorageId>(location.storage_id), aci_fah, program_info.aci_fah_size, acid_fac, program_info.acid_fac_size));
|
||||||
R_TRY(sm::manager::RegisterProcess(process_id, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size));
|
R_TRY(sm::manager::RegisterProcess(process_id, location.title_id, acid_sac, program_info.acid_sac_size, aci_sac, program_info.aci_sac_size));
|
||||||
|
|
||||||
/* Set flags. */
|
/* Set flags. */
|
||||||
if (is_application) {
|
if (is_application) {
|
||||||
|
|
|
@ -74,16 +74,78 @@ namespace {
|
||||||
|
|
||||||
constexpr u32 PrivilegedFileAccessHeader[0x1C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000};
|
constexpr u32 PrivilegedFileAccessHeader[0x1C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000};
|
||||||
constexpr u32 PrivilegedFileAccessControl[0x2C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
|
constexpr u32 PrivilegedFileAccessControl[0x2C / sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
|
||||||
|
constexpr u8 PrivilegedServiceAccessControl[] = {0x80, '*', 0x00, '*'};
|
||||||
constexpr size_t ProcessCountMax = 0x40;
|
constexpr size_t ProcessCountMax = 0x40;
|
||||||
|
|
||||||
|
/* TODO: Libstratosphere this stuff during fatal/creport rewrite. */
|
||||||
|
enum class DebugEventType : u32 {
|
||||||
|
AttachProcess = 0,
|
||||||
|
AttachThread = 1,
|
||||||
|
ExitProcess = 2,
|
||||||
|
ExitThread = 3,
|
||||||
|
Exception = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AttachProcessInfo {
|
||||||
|
sts::ncm::TitleId title_id;
|
||||||
|
u64 process_id;
|
||||||
|
char name[0xC];
|
||||||
|
u32 flags;
|
||||||
|
u64 user_exception_context_address; /* 5.0.0+ */
|
||||||
|
};
|
||||||
|
|
||||||
|
union DebugInfo {
|
||||||
|
AttachProcessInfo attach_process;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DebugEventInfo {
|
||||||
|
DebugEventType type;
|
||||||
|
u32 flags;
|
||||||
|
u64 thread_id;
|
||||||
|
union {
|
||||||
|
DebugInfo info;
|
||||||
|
u64 _[0x40/sizeof(u64)];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This uses debugging SVCs to retrieve a process's title id. */
|
||||||
|
sts::ncm::TitleId GetProcessTitleId(u64 process_id) {
|
||||||
|
/* Get a debug handle, or return our title id. */
|
||||||
|
AutoHandle debug_handle;
|
||||||
|
if (R_FAILED(svcDebugActiveProcess(debug_handle.GetPointer(), process_id))) {
|
||||||
|
u64 current_process_id = 0;
|
||||||
|
R_ASSERT(svcGetProcessId(¤t_process_id, CUR_PROCESS_HANDLE));
|
||||||
|
if (current_process_id == process_id) {
|
||||||
|
return __stratosphere_title_id;
|
||||||
|
} else {
|
||||||
|
/* If we fail to debug a process other than our own, abort. */
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop until we get the event that tells us about the process. */
|
||||||
|
DebugEventInfo d;
|
||||||
|
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()))) {
|
||||||
|
if (d.type == DebugEventType::AttachProcess) {
|
||||||
|
return d.info.attach_process.title_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we somehow didn't get the event, abort. */
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
/* This works around a bug fixed by FS in 4.0.0. */
|
/* This works around a bug fixed by FS in 4.0.0. */
|
||||||
/* Not doing so will cause KIPs with higher process IDs than 7 to be unable to use filesystem services. */
|
/* Not doing so will cause KIPs with higher process IDs than 7 to be unable to use filesystem services. */
|
||||||
void RegisterPrivilegedProcessWithFs(u64 process_id) {
|
/* It also registers privileged processes with SM, so that their title IDs can be known. */
|
||||||
|
void RegisterPrivilegedProcess(u64 process_id) {
|
||||||
fsprUnregisterProgram(process_id);
|
fsprUnregisterProgram(process_id);
|
||||||
fsprRegisterProgram(process_id, process_id, FsStorageId_NandSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl));
|
fsprRegisterProgram(process_id, process_id, FsStorageId_NandSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl));
|
||||||
|
sts::sm::manager::UnregisterProcess(process_id);
|
||||||
|
sts::sm::manager::RegisterProcess(process_id, GetProcessTitleId(process_id), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterPrivilegedProcessesWithFs() {
|
void RegisterPrivilegedProcesses() {
|
||||||
/* Get privileged process range. */
|
/* Get privileged process range. */
|
||||||
u64 min_priv_process_id = 0, max_priv_process_id = 0;
|
u64 min_priv_process_id = 0, max_priv_process_id = 0;
|
||||||
sts::cfg::GetInitialProcessRange(&min_priv_process_id, &max_priv_process_id);
|
sts::cfg::GetInitialProcessRange(&min_priv_process_id, &max_priv_process_id);
|
||||||
|
@ -94,7 +156,7 @@ namespace {
|
||||||
R_ASSERT(svcGetProcessList(&num_pids, pids, ProcessCountMax));
|
R_ASSERT(svcGetProcessList(&num_pids, pids, ProcessCountMax));
|
||||||
for (size_t i = 0; i < num_pids; i++) {
|
for (size_t i = 0; i < num_pids; i++) {
|
||||||
if (min_priv_process_id <= pids[i] && pids[i] <= max_priv_process_id) {
|
if (min_priv_process_id <= pids[i] && pids[i] <= max_priv_process_id) {
|
||||||
RegisterPrivilegedProcessWithFs(pids[i]);
|
RegisterPrivilegedProcess(pids[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,12 +168,13 @@ void __appInit(void) {
|
||||||
|
|
||||||
DoWithSmSession([&]() {
|
DoWithSmSession([&]() {
|
||||||
R_ASSERT(fsprInitialize());
|
R_ASSERT(fsprInitialize());
|
||||||
|
R_ASSERT(smManagerInitialize());
|
||||||
|
|
||||||
/* This works around a bug with process permissions on < 4.0.0. */
|
/* This works around a bug with process permissions on < 4.0.0. */
|
||||||
RegisterPrivilegedProcessesWithFs();
|
/* It also informs SM of privileged process information. */
|
||||||
|
RegisterPrivilegedProcesses();
|
||||||
|
|
||||||
/* Use AMS manager extension to tell SM that FS has been worked around. */
|
/* Use AMS manager extension to tell SM that FS has been worked around. */
|
||||||
R_ASSERT(smManagerInitialize());
|
|
||||||
R_ASSERT(sts::sm::manager::EndInitialDefers());
|
R_ASSERT(sts::sm::manager::EndInitialDefers());
|
||||||
|
|
||||||
R_ASSERT(lrInitialize());
|
R_ASSERT(lrInitialize());
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#include <stratosphere/cfg.hpp>
|
||||||
|
#include <stratosphere/ncm.hpp>
|
||||||
#include <stratosphere/sm.hpp>
|
#include <stratosphere/sm.hpp>
|
||||||
|
|
||||||
#include "sm_service_manager.hpp"
|
#include "sm_service_manager.hpp"
|
||||||
|
@ -32,6 +34,7 @@ namespace sts::sm::impl {
|
||||||
/* Types. */
|
/* Types. */
|
||||||
struct ProcessInfo {
|
struct ProcessInfo {
|
||||||
u64 pid;
|
u64 pid;
|
||||||
|
ncm::TitleId tid;
|
||||||
size_t access_control_size;
|
size_t access_control_size;
|
||||||
u8 access_control[AccessControlSizeMax];
|
u8 access_control[AccessControlSizeMax];
|
||||||
|
|
||||||
|
@ -41,11 +44,15 @@ namespace sts::sm::impl {
|
||||||
|
|
||||||
void Free() {
|
void Free() {
|
||||||
this->pid = InvalidProcessId;
|
this->pid = InvalidProcessId;
|
||||||
|
this->tid = ncm::TitleId::Invalid;
|
||||||
this->access_control_size = 0;
|
this->access_control_size = 0;
|
||||||
std::memset(this->access_control, 0, sizeof(this->access_control));
|
std::memset(this->access_control, 0, sizeof(this->access_control));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Forward declaration, for use in ServiceInfo. */
|
||||||
|
ncm::TitleId GetTitleIdForMitm(u64 pid);
|
||||||
|
|
||||||
struct ServiceInfo {
|
struct ServiceInfo {
|
||||||
ServiceName name;
|
ServiceName name;
|
||||||
u64 owner_pid;
|
u64 owner_pid;
|
||||||
|
@ -95,9 +102,10 @@ namespace sts::sm::impl {
|
||||||
this->mitm_pid = InvalidProcessId;
|
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. */
|
/* Copy to output. */
|
||||||
*out_pid = this->mitm_waiting_ack_pid;
|
*out_pid = this->mitm_waiting_ack_pid;
|
||||||
|
*out_tid = GetTitleIdForMitm(this->mitm_waiting_ack_pid);
|
||||||
*out_hnd = this->mitm_fwd_sess_h.Move();
|
*out_hnd = this->mitm_fwd_sess_h.Move();
|
||||||
this->mitm_waiting_ack = false;
|
this->mitm_waiting_ack = false;
|
||||||
this->mitm_waiting_ack_pid = InvalidProcessId;
|
this->mitm_waiting_ack_pid = InvalidProcessId;
|
||||||
|
@ -149,27 +157,13 @@ namespace sts::sm::impl {
|
||||||
};
|
};
|
||||||
|
|
||||||
class InitialProcessIdLimits {
|
class InitialProcessIdLimits {
|
||||||
public:
|
|
||||||
static constexpr u64 InitialProcessIdMin = 0x00;
|
|
||||||
static constexpr u64 InitialProcessIdMax = 0x50;
|
|
||||||
private:
|
private:
|
||||||
u64 min;
|
u64 min;
|
||||||
u64 max;
|
u64 max;
|
||||||
public:
|
public:
|
||||||
InitialProcessIdLimits() {
|
InitialProcessIdLimits() {
|
||||||
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_500) {
|
/* Retrieve process limits. */
|
||||||
/* On 5.0.0+, we can get precise limits from svcGetSystemInfo. */
|
cfg::GetInitialProcessRange(&this->min, &this->max);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure range is sane. */
|
/* Ensure range is sane. */
|
||||||
if (this->min > this->max) {
|
if (this->min > this->max) {
|
||||||
|
@ -301,6 +295,15 @@ namespace sts::sm::impl {
|
||||||
return pid != InvalidProcessId;
|
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) {
|
bool ShouldDeferForInit(ServiceName service) {
|
||||||
/* Once end has been called, we're done. */
|
/* Once end has been called, we're done. */
|
||||||
if (g_ended_initial_defers) {
|
if (g_ended_initial_defers) {
|
||||||
|
@ -321,10 +324,12 @@ namespace sts::sm::impl {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
u64 cmd_id;
|
u64 cmd_id;
|
||||||
u64 pid;
|
u64 pid;
|
||||||
|
ncm::TitleId tid;
|
||||||
} *info = ((decltype(info))ipcPrepareHeader(&c, sizeof(*info)));
|
} *info = ((decltype(info))ipcPrepareHeader(&c, sizeof(*info)));
|
||||||
info->magic = SFCI_MAGIC;
|
info->magic = SFCI_MAGIC;
|
||||||
info->cmd_id = 65000;
|
info->cmd_id = 65000;
|
||||||
info->pid = pid;
|
info->pid = pid;
|
||||||
|
info->tid = GetTitleIdForMitm(pid);
|
||||||
R_TRY(ipcDispatch(service_info->mitm_query_h.Get()));
|
R_TRY(ipcDispatch(service_info->mitm_query_h.Get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,9 +419,9 @@ namespace sts::sm::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process management. */
|
/* 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. */
|
/* Check that access control will fit in the ServiceInfo. */
|
||||||
if (aci0_sac_size > AccessControlSizeMax) {
|
if (aci_sac_size > AccessControlSizeMax) {
|
||||||
return ResultSmTooLargeAccessControl;
|
return ResultSmTooLargeAccessControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,15 +432,16 @@ namespace sts::sm::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate restrictions. */
|
/* Validate restrictions. */
|
||||||
if (!aci0_sac_size) {
|
if (!aci_sac_size) {
|
||||||
return ResultSmNotAllowed;
|
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. */
|
/* Save info. */
|
||||||
proc->pid = pid;
|
proc->pid = pid;
|
||||||
proc->access_control_size = aci0_sac_size;
|
proc->tid = tid;
|
||||||
std::memcpy(proc->access_control, aci0_sac, proc->access_control_size);
|
proc->access_control_size = aci_sac_size;
|
||||||
|
std::memcpy(proc->access_control, aci_sac, proc->access_control_size);
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,7 +668,7 @@ namespace sts::sm::impl {
|
||||||
return ResultSuccess;
|
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. */
|
/* Validate service name. */
|
||||||
R_TRY(ValidateServiceName(service));
|
R_TRY(ValidateServiceName(service));
|
||||||
|
|
||||||
|
@ -686,30 +692,7 @@ namespace sts::sm::impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Acknowledge. */
|
/* Acknowledge. */
|
||||||
service_info->AcknowledgeMitmSession(out_pid, out_hnd);
|
service_info->AcknowledgeMitmSession(out_pid, out_tid, 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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere/sm.hpp>
|
#include <stratosphere/sm.hpp>
|
||||||
|
#include <stratosphere/ncm.hpp>
|
||||||
|
|
||||||
namespace sts::sm::impl {
|
namespace sts::sm::impl {
|
||||||
|
|
||||||
/* Process management. */
|
/* 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);
|
Result UnregisterProcess(u64 pid);
|
||||||
|
|
||||||
/* Service management. */
|
/* Service management. */
|
||||||
|
@ -37,8 +38,7 @@ namespace sts::sm::impl {
|
||||||
Result WaitMitm(ServiceName service);
|
Result WaitMitm(ServiceName service);
|
||||||
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service);
|
Result InstallMitm(Handle *out, Handle *out_query, u64 pid, ServiceName service);
|
||||||
Result UninstallMitm(u64 pid, ServiceName service);
|
Result UninstallMitm(u64 pid, ServiceName service);
|
||||||
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);
|
||||||
Result AssociatePidTidForMitm(u64 pid, u64 tid);
|
|
||||||
|
|
||||||
/* Dmnt record extensions. */
|
/* Dmnt record extensions. */
|
||||||
Result GetServiceRecord(ServiceRecord *out, ServiceName service);
|
Result GetServiceRecord(ServiceRecord *out, ServiceName service);
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
|
|
||||||
namespace sts::sm {
|
namespace sts::sm {
|
||||||
|
|
||||||
Result ManagerService::RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac) {
|
Result ManagerService::RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci_sac) {
|
||||||
return impl::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements);
|
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) {
|
Result ManagerService::UnregisterProcess(u64 pid) {
|
||||||
|
@ -38,4 +38,9 @@ namespace sts::sm {
|
||||||
R_ASSERT(impl::HasMitm(out.GetPointer(), service));
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include <stratosphere/sm.hpp>
|
#include <stratosphere/sm.hpp>
|
||||||
|
#include <stratosphere/ncm.hpp>
|
||||||
|
|
||||||
namespace sts::sm {
|
namespace sts::sm {
|
||||||
|
|
||||||
|
@ -26,18 +27,20 @@ namespace sts::sm {
|
||||||
protected:
|
protected:
|
||||||
/* Command IDs. */
|
/* Command IDs. */
|
||||||
enum class CommandId {
|
enum class CommandId {
|
||||||
RegisterProcess = 0,
|
RegisterProcess = 0,
|
||||||
UnregisterProcess = 1,
|
UnregisterProcess = 1,
|
||||||
|
|
||||||
AtmosphereEndInitDefers = 65000,
|
AtmosphereEndInitDefers = 65000,
|
||||||
AtmosphereHasMitm = 65001,
|
AtmosphereHasMitm = 65001,
|
||||||
|
AtmosphereRegisterProcess = 65002,
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
/* Actual commands. */
|
/* 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 Result UnregisterProcess(u64 pid);
|
||||||
virtual void AtmosphereEndInitDefers();
|
virtual void AtmosphereEndInitDefers();
|
||||||
virtual void AtmosphereHasMitm(Out<bool> out, ServiceName service);
|
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:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
MAKE_SERVICE_COMMAND_META(ManagerService, RegisterProcess),
|
MAKE_SERVICE_COMMAND_META(ManagerService, RegisterProcess),
|
||||||
|
@ -45,6 +48,7 @@ namespace sts::sm {
|
||||||
|
|
||||||
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereEndInitDefers),
|
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereEndInitDefers),
|
||||||
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereHasMitm),
|
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereHasMitm),
|
||||||
|
MAKE_SERVICE_COMMAND_META(ManagerService, AtmosphereRegisterProcess),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -60,14 +60,9 @@ namespace sts::sm {
|
||||||
return impl::UninstallMitm(this->pid, service);
|
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());
|
R_TRY(this->EnsureInitialized());
|
||||||
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
|
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), client_tid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
|
||||||
}
|
|
||||||
|
|
||||||
Result UserService::AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid) {
|
|
||||||
R_TRY(this->EnsureInitialized());
|
|
||||||
return impl::AssociatePidTidForMitm(pid, tid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result UserService::AtmosphereHasMitm(Out<bool> out, ServiceName service) {
|
Result UserService::AtmosphereHasMitm(Out<bool> out, ServiceName service) {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include <stratosphere/sm.hpp>
|
#include <stratosphere/sm.hpp>
|
||||||
|
#include <stratosphere/ncm.hpp>
|
||||||
|
|
||||||
namespace sts::sm {
|
namespace sts::sm {
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ namespace sts::sm {
|
||||||
|
|
||||||
AtmosphereInstallMitm = 65000,
|
AtmosphereInstallMitm = 65000,
|
||||||
AtmosphereUninstallMitm = 65001,
|
AtmosphereUninstallMitm = 65001,
|
||||||
AtmosphereAssociatePidTidForMitm = 65002,
|
/* Deprecated: AtmosphereAssociatePidTidForMitm = 65002 */
|
||||||
AtmosphereAcknowledgeMitmSession = 65003,
|
AtmosphereAcknowledgeMitmSession = 65003,
|
||||||
AtmosphereHasMitm = 65004,
|
AtmosphereHasMitm = 65004,
|
||||||
AtmosphereWaitMitm = 65005,
|
AtmosphereWaitMitm = 65005,
|
||||||
|
@ -56,8 +57,7 @@ namespace sts::sm {
|
||||||
/* Atmosphere commands. */
|
/* Atmosphere commands. */
|
||||||
virtual Result AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, ServiceName service);
|
virtual Result AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, ServiceName service);
|
||||||
virtual Result AtmosphereUninstallMitm(ServiceName service);
|
virtual Result AtmosphereUninstallMitm(ServiceName service);
|
||||||
virtual Result AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid);
|
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<ncm::TitleId> client_tid, Out<MovedHandle> fwd_h, ServiceName service);
|
||||||
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service);
|
|
||||||
virtual Result AtmosphereHasMitm(Out<bool> out, ServiceName service);
|
virtual Result AtmosphereHasMitm(Out<bool> out, ServiceName service);
|
||||||
virtual Result AtmosphereWaitMitm(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, AtmosphereInstallMitm),
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereUninstallMitm),
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereUninstallMitm),
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAssociatePidTidForMitm),
|
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAcknowledgeMitmSession),
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereAcknowledgeMitmSession),
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasMitm),
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereHasMitm),
|
||||||
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereWaitMitm),
|
MAKE_SERVICE_COMMAND_META(UserService, AtmosphereWaitMitm),
|
||||||
|
|
Loading…
Reference in a new issue