mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-06-04 00:28:51 -04:00
Stratosphere: Fix FS permissions for <4.0.0 KIPs
This commit is contained in:
parent
781f2597e5
commit
5dc31f001e
10 changed files with 183 additions and 15 deletions
|
@ -34,7 +34,7 @@ ARCH := -march=armv8-a -mtune=cortex-a57 -mtp=soft -fPIE
|
|||
CFLAGS := -g -Wall -O2 -ffunction-sections \
|
||||
$(ARCH) $(DEFINES)
|
||||
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DSM_ENABLE_SMHAX -DSM_ENABLE_MITM -DSM_MINIMUM_SESSION_LIMIT=8
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DSM_ENABLE_SMHAX -DSM_ENABLE_MITM -DSM_ENABLE_INIT_DEFERS -DSM_MINIMUM_SESSION_LIMIT=8
|
||||
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ Result ManagerService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_
|
|||
case Manager_Cmd_UnregisterProcess:
|
||||
rc = WrapIpcCommandImpl<&ManagerService::unregister_process>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
case Manager_Cmd_AtmosphereEndInitDefers:
|
||||
rc = WrapIpcCommandImpl<&ManagerService::end_init_defers>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -47,3 +50,9 @@ std::tuple<Result> ManagerService::register_process(u64 pid, InBuffer<u8> acid_s
|
|||
std::tuple<Result> ManagerService::unregister_process(u64 pid) {
|
||||
return {Registration::UnregisterProcess(pid)};
|
||||
}
|
||||
|
||||
std::tuple<Result> ManagerService::end_init_defers() {
|
||||
Registration::EndInitDefers();
|
||||
return {0};
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
|
||||
enum ManagerServiceCmd {
|
||||
Manager_Cmd_RegisterProcess = 0,
|
||||
Manager_Cmd_UnregisterProcess = 1
|
||||
Manager_Cmd_UnregisterProcess = 1,
|
||||
|
||||
|
||||
Manager_Cmd_AtmosphereEndInitDefers = 65000,
|
||||
};
|
||||
|
||||
class ManagerService final : public IServiceObject {
|
||||
|
@ -36,4 +39,5 @@ class ManagerService final : public IServiceObject {
|
|||
/* Actual commands. */
|
||||
std::tuple<Result> register_process(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac);
|
||||
std::tuple<Result> unregister_process(u64 pid);
|
||||
std::tuple<Result> end_init_defers();
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -46,6 +46,9 @@ class Registration {
|
|||
};
|
||||
|
||||
/* Utilities. */
|
||||
static void EndInitDefers();
|
||||
static bool ShouldInitDefer(u64 service);
|
||||
|
||||
static Registration::Process *GetProcessForPid(u64 pid);
|
||||
static Registration::Process *GetFreeProcess();
|
||||
static Registration::Service *GetService(u64 service);
|
||||
|
|
|
@ -53,7 +53,7 @@ Result UserService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id,
|
|||
|
||||
Result UserService::handle_deferred() {
|
||||
/* If we're deferred, GetService failed. */
|
||||
return WrapDeferredIpcCommandImpl<&UserService::deferred_get_service>(this, this->deferred_service);;
|
||||
return WrapDeferredIpcCommandImpl<&UserService::deferred_get_service>(this, this->deferred_service);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue