Stratosphere: Fix FS permissions for <4.0.0 KIPs

This commit is contained in:
Michael Scire
2018-10-17 16:26:36 -07:00
parent 781f2597e5
commit 5dc31f001e
10 changed files with 183 additions and 15 deletions

View File

@@ -26,6 +26,7 @@ static std::array<Registration::Service, REGISTRATION_LIST_MAX_SERVICE> g_servic
static u64 g_initial_process_id_low = 0;
static u64 g_initial_process_id_high = 0;
static bool g_determined_initial_process_ids = false;
static bool g_end_init_defers = false;
u64 GetServiceNameLength(u64 service) {
u64 service_name_len = 0;
@@ -36,6 +37,38 @@ u64 GetServiceNameLength(u64 service) {
return service_name_len;
}
/* Atmosphere extension utilities. */
void Registration::EndInitDefers() {
g_end_init_defers = true;
}
constexpr u64 EncodeNameConstant(const char *name) {
u64 service = 0;
for (unsigned int i = 0; i < sizeof(service); i++) {
if (name[i] == '\x00') {
break;
}
service |= ((u64)name[i]) << (8 * i);
}
return service;
}
bool Registration::ShouldInitDefer(u64 service) {
/* Only enable if compile-time generated. */
#ifndef SM_ENABLE_INIT_DEFERS
return false;
#endif
if (g_end_init_defers) {
return false;
}
/* This is a mechanism by which certain services will always be deferred until sm:m receives a special command. */
/* This can be extended with more services as needed at a later date. */
constexpr u64 FSP_SRV = EncodeNameConstant("fsp-srv");
return service == FSP_SRV;
}
/* Utilities. */
Registration::Process *Registration::GetProcessForPid(u64 pid) {
auto process_it = std::find_if(g_process_list.begin(), g_process_list.end(), member_equals_fn(&Process::pid, pid));
@@ -188,11 +221,13 @@ bool Registration::HasService(u64 service) {
Result Registration::GetServiceHandle(u64 pid, u64 service, Handle *out) {
Registration::Service *target_service = GetService(service);
if (target_service == NULL) {
if (target_service == NULL || ShouldInitDefer(service)) {
/* Note: This defers the result until later. */
return RESULT_DEFER_SESSION;
}
/* */
*out = 0;
Result rc;
if (target_service->mitm_pid == 0 || target_service->mitm_pid == pid) {