mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +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 {
|
||||
|
||||
/* Convenience definitions. */
|
||||
constexpr os::ProcessId InitialProcessIdMinDeprecated = {0x00};
|
||||
constexpr os::ProcessId InitialProcessIdMaxDeprecated = {0x50};
|
||||
|
||||
/* Privileged process globals. */
|
||||
constinit os::SdkMutex g_lock;
|
||||
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_cur_process_id = os::InvalidProcessId;
|
||||
|
||||
/* SD card helpers. */
|
||||
void GetPrivilegedProcessIdRange(os::ProcessId *out_min, os::ProcessId *out_max) {
|
||||
os::ProcessId min = os::InvalidProcessId, max = os::InvalidProcessId;
|
||||
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;
|
||||
ALWAYS_INLINE void EnsurePrivilegedProcessStatusCached() {
|
||||
if (AMS_LIKELY(g_got_privileged_process_status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
*out_min = min;
|
||||
*out_max = max;
|
||||
}
|
||||
std::scoped_lock lk(g_lock);
|
||||
|
||||
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;
|
||||
if (AMS_LIKELY(!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));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Privileged Process utilities. */
|
||||
bool IsInitialProcess() {
|
||||
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();
|
||||
}
|
||||
|
||||
/* Determine if we're privileged, and return. */
|
||||
/* Determine if we're Initial. */
|
||||
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) {
|
||||
std::scoped_lock lk(g_lock);
|
||||
|
||||
/* If we've not detected, do detection. */
|
||||
if (!g_got_privileged_process_status) {
|
||||
GetPrivilegedProcessStatus();
|
||||
}
|
||||
/* Cache initial process range and extents. */
|
||||
EnsurePrivilegedProcessStatusCached();
|
||||
|
||||
/* Set output. */
|
||||
*out_min = g_min_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. */
|
||||
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. */
|
||||
os::ManagedHandle debug_handle;
|
||||
R_ABORT_UNLESS(svcDebugActiveProcess(debug_handle.GetPointer(), static_cast<u64>(process_id)));
|
||||
svc::Handle debug_handle;
|
||||
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. */
|
||||
svc::DebugEventInfo d;
|
||||
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) {
|
||||
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. */
|
||||
/* 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. */
|
||||
void RegisterPrivilegedProcess(os::ProcessId process_id) {
|
||||
fsprUnregisterProgram(static_cast<u64>(process_id));
|
||||
fsprRegisterProgram(static_cast<u64>(process_id), static_cast<u64>(process_id), NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl));
|
||||
void RegisterPrivilegedProcess(os::ProcessId process_id, ncm::ProgramId program_id) {
|
||||
fsprUnregisterProgram(process_id.value);
|
||||
fsprRegisterProgram(process_id.value, process_id.value, NcmStorageId_BuiltInSystem, PrivilegedFileAccessHeader, sizeof(PrivilegedFileAccessHeader), PrivilegedFileAccessControl, sizeof(PrivilegedFileAccessControl));
|
||||
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() {
|
||||
|
@ -107,13 +101,17 @@ namespace {
|
|||
os::ProcessId min_priv_process_id = os::InvalidProcessId, max_priv_process_id = os::InvalidProcessId;
|
||||
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. */
|
||||
s32 num_pids;
|
||||
os::ProcessId pids[ProcessCountMax];
|
||||
R_ABORT_UNLESS(svc::GetProcessList(&num_pids, reinterpret_cast<u64 *>(pids), ProcessCountMax));
|
||||
for (s32 i = 0; i < num_pids; i++) {
|
||||
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