mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
pm/cfg: simplify initial process id range logic
This commit is contained in:
parent
18825866ac
commit
65fd967550
2 changed files with 30 additions and 56 deletions
|
@ -19,66 +19,42 @@ namespace ams::cfg {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
/* Convenience definitions. */
|
|
||||||
constexpr os::ProcessId InitialProcessIdMinDeprecated = {0x00};
|
|
||||||
constexpr os::ProcessId InitialProcessIdMaxDeprecated = {0x50};
|
|
||||||
|
|
||||||
/* Privileged process globals. */
|
|
||||||
constinit os::SdkMutex g_lock;
|
constinit os::SdkMutex g_lock;
|
||||||
constinit bool g_got_privileged_process_status = false;
|
constinit bool g_got_privileged_process_status = false;
|
||||||
constinit os::ProcessId g_min_initial_process_id = os::InvalidProcessId, g_max_initial_process_id = os::InvalidProcessId;
|
constinit os::ProcessId g_min_initial_process_id = os::InvalidProcessId, g_max_initial_process_id = os::InvalidProcessId;
|
||||||
constinit os::ProcessId g_cur_process_id = os::InvalidProcessId;
|
constinit os::ProcessId g_cur_process_id = os::InvalidProcessId;
|
||||||
|
|
||||||
/* SD card helpers. */
|
ALWAYS_INLINE void EnsurePrivilegedProcessStatusCached() {
|
||||||
void GetPrivilegedProcessIdRange(os::ProcessId *out_min, os::ProcessId *out_max) {
|
if (AMS_LIKELY(g_got_privileged_process_status)) {
|
||||||
os::ProcessId min = os::InvalidProcessId, max = os::InvalidProcessId;
|
return;
|
||||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
|
||||||
/* On 5.0.0+, we can get precise limits from svcGetSystemInfo. */
|
|
||||||
R_ABORT_UNLESS(svcGetSystemInfo(reinterpret_cast<u64 *>(&min), SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum));
|
|
||||||
R_ABORT_UNLESS(svcGetSystemInfo(reinterpret_cast<u64 *>(&max), SystemInfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum));
|
|
||||||
} else if (hos::GetVersion() >= hos::Version_4_0_0) {
|
|
||||||
/* On 4.0.0-4.1.0, we can get the precise limits from normal svcGetInfo. */
|
|
||||||
R_ABORT_UNLESS(svcGetInfo(reinterpret_cast<u64 *>(&min), InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Minimum));
|
|
||||||
R_ABORT_UNLESS(svcGetInfo(reinterpret_cast<u64 *>(&max), InfoType_InitialProcessIdRange, INVALID_HANDLE, InitialProcessIdRangeInfo_Maximum));
|
|
||||||
} else {
|
|
||||||
/* On < 4.0.0, we just use hardcoded extents. */
|
|
||||||
min = InitialProcessIdMinDeprecated;
|
|
||||||
max = InitialProcessIdMaxDeprecated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_min = min;
|
|
||||||
*out_max = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetPrivilegedProcessStatus() {
|
|
||||||
GetPrivilegedProcessIdRange(&g_min_initial_process_id, &g_max_initial_process_id);
|
|
||||||
g_cur_process_id = os::GetCurrentProcessId();
|
|
||||||
g_got_privileged_process_status = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Privileged Process utilities. */
|
|
||||||
bool IsInitialProcess() {
|
|
||||||
std::scoped_lock lk(g_lock);
|
std::scoped_lock lk(g_lock);
|
||||||
|
|
||||||
/* If we've not detected, do detection. */
|
if (AMS_LIKELY(!g_got_privileged_process_status)) {
|
||||||
if (!g_got_privileged_process_status) {
|
R_ABORT_UNLESS(svc::GetSystemInfo(std::addressof(g_min_initial_process_id.value), svc::SystemInfoType_InitialProcessIdRange, svc::InvalidHandle, svc::InitialProcessIdRangeInfo_Minimum));
|
||||||
GetPrivilegedProcessStatus();
|
R_ABORT_UNLESS(svc::GetSystemInfo(std::addressof(g_max_initial_process_id.value), svc::SystemInfoType_InitialProcessIdRange, svc::InvalidHandle, svc::InitialProcessIdRangeInfo_Maximum));
|
||||||
|
g_cur_process_id = os::GetCurrentProcessId();
|
||||||
|
|
||||||
|
g_got_privileged_process_status = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if we're privileged, and return. */
|
}
|
||||||
|
|
||||||
|
bool IsInitialProcess() {
|
||||||
|
/* Cache initial process range and extents. */
|
||||||
|
EnsurePrivilegedProcessStatusCached();
|
||||||
|
|
||||||
|
/* Determine if we're Initial. */
|
||||||
return g_min_initial_process_id <= g_cur_process_id && g_cur_process_id <= g_max_initial_process_id;
|
return g_min_initial_process_id <= g_cur_process_id && g_cur_process_id <= g_max_initial_process_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetInitialProcessRange(os::ProcessId *out_min, os::ProcessId *out_max) {
|
void GetInitialProcessRange(os::ProcessId *out_min, os::ProcessId *out_max) {
|
||||||
std::scoped_lock lk(g_lock);
|
/* Cache initial process range and extents. */
|
||||||
|
EnsurePrivilegedProcessStatusCached();
|
||||||
/* If we've not detected, do detection. */
|
|
||||||
if (!g_got_privileged_process_status) {
|
|
||||||
GetPrivilegedProcessStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Set output. */
|
||||||
*out_min = g_min_initial_process_id;
|
*out_min = g_min_initial_process_id;
|
||||||
*out_max = g_max_initial_process_id;
|
*out_max = g_max_initial_process_id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,21 +71,15 @@ namespace {
|
||||||
|
|
||||||
/* This uses debugging SVCs to retrieve a process's program id. */
|
/* This uses debugging SVCs to retrieve a process's program id. */
|
||||||
ncm::ProgramId GetProcessProgramId(os::ProcessId process_id) {
|
ncm::ProgramId GetProcessProgramId(os::ProcessId process_id) {
|
||||||
/* Check if we should return our program id. */
|
|
||||||
/* Doing this here works around a bug fixed in 6.0.0. */
|
|
||||||
/* Not doing so will cause svcDebugActiveProcess to deadlock on lower firmwares if called for it's own process. */
|
|
||||||
if (process_id == os::GetCurrentProcessId()) {
|
|
||||||
return os::GetCurrentProgramId();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get a debug handle. */
|
/* Get a debug handle. */
|
||||||
os::ManagedHandle debug_handle;
|
svc::Handle debug_handle;
|
||||||
R_ABORT_UNLESS(svcDebugActiveProcess(debug_handle.GetPointer(), static_cast<u64>(process_id)));
|
R_ABORT_UNLESS(svc::DebugActiveProcess(std::addressof(debug_handle), process_id.value));
|
||||||
|
ON_SCOPE_EXIT { R_ABORT_UNLESS(svc::CloseHandle(debug_handle)); };
|
||||||
|
|
||||||
/* Loop until we get the event that tells us about the process. */
|
/* Loop until we get the event that tells us about the process. */
|
||||||
svc::DebugEventInfo d;
|
svc::DebugEventInfo d;
|
||||||
while (true) {
|
while (true) {
|
||||||
R_ABORT_UNLESS(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()));
|
R_ABORT_UNLESS(svc::GetDebugEvent(std::addressof(d), debug_handle));
|
||||||
if (d.type == svc::DebugEvent_CreateProcess) {
|
if (d.type == svc::DebugEvent_CreateProcess) {
|
||||||
return ncm::ProgramId{d.info.create_process.program_id};
|
return ncm::ProgramId{d.info.create_process.program_id};
|
||||||
}
|
}
|
||||||
|
@ -95,11 +89,11 @@ namespace {
|
||||||
/* 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. */
|
||||||
/* It also registers privileged processes with SM, so that their program ids can be known. */
|
/* It also registers privileged processes with SM, so that their program ids can be known. */
|
||||||
void RegisterPrivilegedProcess(os::ProcessId process_id) {
|
void RegisterPrivilegedProcess(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||||
fsprUnregisterProgram(static_cast<u64>(process_id));
|
fsprUnregisterProgram(process_id.value);
|
||||||
fsprRegisterProgram(static_cast<u64>(process_id), static_cast<u64>(process_id), NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl));
|
fsprRegisterProgram(process_id.value, process_id.value, NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl));
|
||||||
sm::manager::UnregisterProcess(process_id);
|
sm::manager::UnregisterProcess(process_id);
|
||||||
sm::manager::RegisterProcess(process_id, GetProcessProgramId(process_id), cfg::OverrideStatus{}, PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl));
|
sm::manager::RegisterProcess(process_id, program_id, cfg::OverrideStatus{}, PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl), PrivilegedServiceAccessControl, sizeof(PrivilegedServiceAccessControl));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterPrivilegedProcesses() {
|
void RegisterPrivilegedProcesses() {
|
||||||
|
@ -107,13 +101,17 @@ namespace {
|
||||||
os::ProcessId min_priv_process_id = os::InvalidProcessId, max_priv_process_id = os::InvalidProcessId;
|
os::ProcessId min_priv_process_id = os::InvalidProcessId, max_priv_process_id = os::InvalidProcessId;
|
||||||
cfg::GetInitialProcessRange(&min_priv_process_id, &max_priv_process_id);
|
cfg::GetInitialProcessRange(&min_priv_process_id, &max_priv_process_id);
|
||||||
|
|
||||||
|
/* Get current process id/program id. */
|
||||||
|
const auto cur_process_id = os::GetCurrentProcessId();
|
||||||
|
const auto cur_program_id = os::GetCurrentProgramId();
|
||||||
|
|
||||||
/* Get list of processes, register all privileged ones. */
|
/* Get list of processes, register all privileged ones. */
|
||||||
s32 num_pids;
|
s32 num_pids;
|
||||||
os::ProcessId pids[ProcessCountMax];
|
os::ProcessId pids[ProcessCountMax];
|
||||||
R_ABORT_UNLESS(svc::GetProcessList(&num_pids, reinterpret_cast<u64 *>(pids), ProcessCountMax));
|
R_ABORT_UNLESS(svc::GetProcessList(&num_pids, reinterpret_cast<u64 *>(pids), ProcessCountMax));
|
||||||
for (s32 i = 0; i < num_pids; i++) {
|
for (s32 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) {
|
||||||
RegisterPrivilegedProcess(pids[i]);
|
RegisterPrivilegedProcess(pids[i], pids[i] == cur_process_id ? cur_program_id : GetProcessProgramId(pids[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue