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

@@ -28,6 +28,7 @@
#include "pm_process_track.hpp"
#include "pm_registration.hpp"
#include "pm_debug_monitor.hpp"
#include "smm_ams.h"
extern "C" {
extern u32 __start__;
@@ -56,6 +57,20 @@ void __libnx_initheap(void) {
fake_heap_end = (char*)addr + size;
}
void RegisterPrivilegedProcessesWithFs() {
/* Ensures that all privileged processes are registered with full FS permissions. */
constexpr u64 PRIVILEGED_PROCESS_MIN = 0;
constexpr u64 PRIVILEGED_PROCESS_MAX = 0x4F;
const u32 PRIVILEGED_FAH[0x1C/sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x0000001C, 0x00000000, 0x0000001C, 0x00000000};
const u32 PRIVILEGED_FAC[0x2C/sizeof(u32)] = {0x00000001, 0x00000000, 0x80000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF};
for (u64 pid = PRIVILEGED_PROCESS_MIN; pid <= PRIVILEGED_PROCESS_MAX; pid++) {
fsprUnregisterProgram(pid);
fsprRegisterProgram(pid, pid, FsStorageId_NandSystem, PRIVILEGED_FAH, sizeof(PRIVILEGED_FAH), PRIVILEGED_FAC, sizeof(PRIVILEGED_FAC));
}
}
void __appInit(void) {
Result rc;
@@ -64,27 +79,33 @@ void __appInit(void) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_SM));
}
rc = fsInitialize();
if (R_FAILED(rc)) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
}
rc = lrInitialize();
rc = fsprInitialize();
if (R_FAILED(rc)) {
fatalSimple(0xCAFE << 4 | 1);
}
rc = fsprInitialize();
if (R_FAILED(rc)) {
/* This works around a bug with process permissions on < 4.0.0. */
RegisterPrivilegedProcessesWithFs();
rc = smManagerAmsInitialize();
if (R_SUCCEEDED(rc)) {
smManagerAmsEndInitialDefers();
smManagerAmsExit();
} else {
fatalSimple(0xCAFE << 4 | 2);
}
rc = ldrPmInitialize();
rc = smManagerInitialize();
if (R_FAILED(rc)) {
fatalSimple(0xCAFE << 4 | 3);
}
rc = lrInitialize();
if (R_FAILED(rc)) {
fatalSimple(0xCAFE << 4 | 4);
}
rc = smManagerInitialize();
rc = ldrPmInitialize();
if (R_FAILED(rc)) {
fatalSimple(0xCAFE << 4 | 5);
}
@@ -94,6 +115,11 @@ void __appInit(void) {
fatalSimple(0xCAFE << 4 | 6);
}
rc = fsInitialize();
if (R_FAILED(rc)) {
fatalSimple(MAKERESULT(Module_Libnx, LibnxError_InitFail_FS));
}
CheckAtmosphereVersion();
}

View File

@@ -182,7 +182,8 @@ void ResourceLimitUtils::InitializeLimits() {
/* Atmosphere: Allocate extra memory (24 MiB) to SYSTEM away from Applet. */
for (unsigned int i = 0; i < 6; i++) {
g_memory_resource_limits[i][0] += ATMOSPHERE_EXTRA_SYSTEM_MEMORY_FOR_SYSMODULES;
g_memory_resource_limits[i][2] -= ATMOSPHERE_EXTRA_SYSTEM_MEMORY_FOR_SYSMODULES;
//g_memory_resource_limits[i][2] -= ATMOSPHERE_EXTRA_SYSTEM_MEMORY_FOR_SYSMODULES;
g_memory_resource_limits[i][1] -= ATMOSPHERE_EXTRA_SYSTEM_MEMORY_FOR_SYSMODULES;
}
/* Set resource limits. */

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 2018 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <switch.h>
#include <switch/arm/atomics.h>
#include "smm_ams.h"
static Service g_smManagerAmsSrv;
static u64 g_smManagerAmsRefcnt;
Result smManagerAmsInitialize(void) {
atomicIncrement64(&g_smManagerAmsRefcnt);
if (serviceIsActive(&g_smManagerAmsSrv))
return 0;
return smGetService(&g_smManagerAmsSrv, "sm:m");
}
void smManagerAmsExit(void) {
if (atomicDecrement64(&g_smManagerAmsRefcnt) == 0)
serviceClose(&g_smManagerAmsSrv);
}
Result smManagerAmsEndInitialDefers(void) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(&g_smManagerAmsSrv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 65000;
Result rc = serviceIpcDispatch(&g_smManagerAmsSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_smManagerAmsSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
}
return rc;
}

View File

@@ -0,0 +1,21 @@
/**
* @file smm_ams.h
* @brief Service manager (sm:m) IPC wrapper for Atmosphere extensions.
* @author SciresM
* @copyright libnx Authors
*/
#pragma once
#include <switch.h>
#ifdef __cplusplus
extern "C" {
#endif
Result smManagerAmsInitialize(void);
void smManagerAmsExit(void);
Result smManagerAmsEndInitialDefers(void);
#ifdef __cplusplus
}
#endif