sm: add HasService/HasMitm, refactor into sts::

This commit is contained in:
Michael Scire 2019-06-24 17:57:49 -07:00
parent 3ccbb34c62
commit 9217e4c5f9
15 changed files with 69 additions and 118 deletions

@ -1 +1 @@
Subproject commit 1d81da1230728993922126f756f6499b24be3eda
Subproject commit cf5c6cdad9ec4066d763c3317e98f7027d3172a6

View file

@ -224,7 +224,7 @@ Result NsoUtils::CalculateNsoLoadExtents(u32 addspace_type, u32 args_size, NsoLo
u64 aslr_slide = 0;
if (addspace_type & 0x20) {
aslr_slide = StratosphereRandomUtils::GetRandomU64((addspace_size - extents->total_size) >> 21) << 21;
aslr_slide = sts::rnd::GenerateRandomU64((addspace_size - extents->total_size) >> 21) << 21;
}
extents->base_address = addspace_start + aslr_slide;

View file

@ -23,6 +23,8 @@
#include <switch.h>
#include <stratosphere.hpp>
#include <stratosphere/sm/sm_manager_api.hpp>
#include "pm_boot2.hpp"
#include "pm_registration.hpp"
#include "pm_boot_mode.hpp"
@ -181,18 +183,15 @@ static void MountSdCard() {
}
static void WaitForMitm(const char *service) {
bool mitm_installed = false;
const auto name = sts::sm::ServiceName::Encode(service);
DoWithSmSession([&]() {
R_ASSERT(smManagerAmsInitialize());
});
ON_SCOPE_EXIT { smManagerAmsExit(); };
while (!mitm_installed) {
R_ASSERT(smManagerAmsHasMitm(&mitm_installed, service));
if (!mitm_installed) {
svcSleepThread(1000000ull);
while (true) {
bool mitm_installed = false;
R_ASSERT(sts::sm::manager::HasMitm(&mitm_installed, name));
if (mitm_installed) {
break;
}
svcSleepThread(1000000ull);
}
}

View file

@ -22,6 +22,7 @@
#include <switch.h>
#include <atmosphere.h>
#include <stratosphere.hpp>
#include <stratosphere/sm/sm_manager_api.hpp>
#include "pm_boot_mode.hpp"
#include "pm_info.hpp"
@ -99,18 +100,14 @@ void __appInit(void) {
DoWithSmSession([&]() {
R_ASSERT(fsprInitialize());
R_ASSERT(smManagerInitialize());
/* This works around a bug with process permissions on < 4.0.0. */
RegisterPrivilegedProcessesWithFs();
/* Use AMS manager extension to tell SM that FS has been worked around. */
{
R_ASSERT(smManagerAmsInitialize());
smManagerAmsEndInitialDefers();
smManagerAmsExit();
}
R_ASSERT(sts::sm::manager::EndInitialDefers());
R_ASSERT(smManagerInitialize());
R_ASSERT(lrInitialize());
R_ASSERT(ldrPmInitialize());
R_ASSERT(splInitialize());

View file

@ -26,7 +26,7 @@ endif
#---------------------------------------------------------------------------------
TARGET := $(notdir $(CURDIR))
BUILD := build
SOURCES := source
SOURCES := source source/impl
DATA := data
INCLUDES := include ../../common/include
EXEFS_SRC := exefs_src

View file

@ -16,10 +16,11 @@
#include <switch.h>
#include <stratosphere.hpp>
#include <stratosphere/sm.hpp>
#include "sm_service_manager.hpp"
namespace sts::sm {
namespace sts::sm::impl {
/* Anonymous namespace for implementation details. */
namespace {
@ -451,6 +452,9 @@ namespace sts::sm {
/* Service management. */
Result HasService(bool *out, ServiceName service) {
/* Validate service name. */
R_TRY(ValidateServiceName(service));
*out = HasServiceInfo(service);
return ResultSuccess;
}

View file

@ -16,9 +16,9 @@
#pragma once
#include <switch.h>
#include "sm_types.hpp"
#include <stratosphere/sm.hpp>
namespace sts::sm {
namespace sts::sm::impl {
/* Process management. */
Result RegisterProcess(u64 pid, const void *acid_sac, size_t acid_sac_size, const void *aci0_sac, size_t aci0_sac_size);

View file

@ -18,16 +18,16 @@
#include <stratosphere.hpp>
#include "sm_dmnt_service.hpp"
#include "sm_service_manager.hpp"
#include "impl/sm_service_manager.hpp"
namespace sts::sm {
Result DmntService::AtmosphereGetRecord(Out<ServiceRecord> record, ServiceName service) {
return sm::GetServiceRecord(record.GetPointer(), service);
return impl::GetServiceRecord(record.GetPointer(), service);
}
void DmntService::AtmosphereListRecords(OutBuffer<ServiceRecord> records, Out<u64> out_count, u64 offset) {
R_ASSERT(sm::ListServiceRecords(records.buffer, out_count.GetPointer(), offset, records.num_elements));
R_ASSERT(impl::ListServiceRecords(records.buffer, out_count.GetPointer(), offset, records.num_elements));
}
void DmntService::AtmosphereGetRecordSize(Out<u64> record_size) {

View file

@ -17,7 +17,7 @@
#pragma once
#include <switch.h>
#include <stratosphere.hpp>
#include "sm_types.hpp"
#include <stratosphere/sm.hpp>
namespace sts::sm {

View file

@ -22,11 +22,12 @@
#include <switch.h>
#include <stratosphere.hpp>
#include "sm_service_manager.hpp"
#include "sm_user_service.hpp"
#include "sm_manager_service.hpp"
#include "sm_dmnt_service.hpp"
#include "impl/sm_service_manager.hpp"
extern "C" {
extern u32 __start__;
@ -75,24 +76,26 @@ void __appExit(void) {
/* Nothing to clean up, because we're sm. */
}
using namespace sts;
int main(int argc, char **argv)
{
/* Create service waitable manager. */
static auto s_server_manager = WaitableManager(1);
/* Create sm:, (and thus allow things to register to it). */
s_server_manager.AddWaitable(new ManagedPortServer<sts::sm::UserService>("sm:", 0x40));
s_server_manager.AddWaitable(new ManagedPortServer<sm::UserService>("sm:", 0x40));
/* Create sm:m manually. */
Handle smm_h;
R_ASSERT(sts::sm::RegisterServiceForSelf(&smm_h, sts::sm::ServiceName::Encode("sm:m"), 1));
s_server_manager.AddWaitable(new ExistingPortServer<sts::sm::ManagerService>(smm_h, 1));
R_ASSERT(sm::impl::RegisterServiceForSelf(&smm_h, sm::ServiceName::Encode("sm:m"), 1));
s_server_manager.AddWaitable(new ExistingPortServer<sm::ManagerService>(smm_h, 1));
/*===== ATMOSPHERE EXTENSION =====*/
/* Create sm:dmnt manually. */
Handle smdmnt_h;
R_ASSERT(sts::sm::RegisterServiceForSelf(&smdmnt_h, sts::sm::ServiceName::Encode("sm:dmnt"), 1));
s_server_manager.AddWaitable(new ExistingPortServer<sts::sm::DmntService>(smm_h, 1));;
R_ASSERT(sm::impl::RegisterServiceForSelf(&smdmnt_h, sm::ServiceName::Encode("sm:dmnt"), 1));
s_server_manager.AddWaitable(new ExistingPortServer<sm::DmntService>(smm_h, 1));;
/*================================*/

View file

@ -18,24 +18,24 @@
#include <stratosphere.hpp>
#include "sm_manager_service.hpp"
#include "sm_service_manager.hpp"
#include "impl/sm_service_manager.hpp"
namespace sts::sm {
Result ManagerService::RegisterProcess(u64 pid, InBuffer<u8> acid_sac, InBuffer<u8> aci0_sac) {
return sm::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements);
return impl::RegisterProcess(pid, acid_sac.buffer, acid_sac.num_elements, aci0_sac.buffer, aci0_sac.num_elements);
}
Result ManagerService::UnregisterProcess(u64 pid) {
return sm::UnregisterProcess(pid);
return impl::UnregisterProcess(pid);
}
void ManagerService::AtmosphereEndInitDefers() {
R_ASSERT(sm::EndInitialDefers());
R_ASSERT(impl::EndInitialDefers());
}
void ManagerService::AtmosphereHasMitm(Out<bool> out, ServiceName service) {
R_ASSERT(sm::HasMitm(out.GetPointer(), service));
R_ASSERT(impl::HasMitm(out.GetPointer(), service));
}
}

View file

@ -17,7 +17,7 @@
#pragma once
#include <switch.h>
#include <stratosphere.hpp>
#include "sm_types.hpp"
#include <stratosphere/sm.hpp>
namespace sts::sm {

View file

@ -1,71 +0,0 @@
/*
* Copyright (c) 2018-2019 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/>.
*/
#pragma once
#include <cstring>
namespace sts::sm {
struct ServiceName {
static constexpr size_t MaxLength = 8;
char name[MaxLength];
static constexpr ServiceName Encode(const char *name, size_t name_size) {
ServiceName out{};
for (size_t i = 0; i < MaxLength; i++) {
if (i < name_size) {
out.name[i] = name[i];
} else {
out.name[i] = 0;
}
}
return out;
}
static constexpr ServiceName Encode(const char *name) {
return Encode(name, std::strlen(name));
}
};
static constexpr ServiceName InvalidServiceName = ServiceName::Encode("");
static_assert(alignof(ServiceName) == 1, "ServiceName definition!");
inline bool operator==(const ServiceName &lhs, const ServiceName &rhs) {
return std::memcmp(&lhs, &rhs, sizeof(ServiceName)) == 0;
}
inline bool operator!=(const ServiceName &lhs, const ServiceName &rhs) {
return !(lhs == rhs);
}
/* For Debug Monitor extensions. */
struct ServiceRecord {
ServiceName service;
u64 owner_pid;
u64 max_sessions;
u64 mitm_pid;
u64 mitm_waiting_ack_pid;
bool is_light;
bool mitm_waiting_ack;
};
static_assert(sizeof(ServiceRecord) == 0x30, "ServiceRecord definition!");
/* For process validation. */
static constexpr u64 InvalidProcessId = static_cast<u64>(-1ull);
}

View file

@ -18,7 +18,7 @@
#include <stratosphere.hpp>
#include "sm_user_service.hpp"
#include "sm_service_manager.hpp"
#include "impl/sm_service_manager.hpp"
namespace sts::sm {
@ -37,37 +37,47 @@ namespace sts::sm {
Result UserService::GetService(Out<MovedHandle> out_h, ServiceName service) {
R_TRY(this->EnsureInitialized());
return sm::GetServiceHandle(out_h.GetHandlePointer(), this->pid, service);
return impl::GetServiceHandle(out_h.GetHandlePointer(), this->pid, service);
}
Result UserService::RegisterService(Out<MovedHandle> out_h, ServiceName service, u32 max_sessions, bool is_light) {
R_TRY(this->EnsureInitialized());
return sm::RegisterService(out_h.GetHandlePointer(), this->pid, service, max_sessions, is_light);
return impl::RegisterService(out_h.GetHandlePointer(), this->pid, service, max_sessions, is_light);
}
Result UserService::UnregisterService(ServiceName service) {
R_TRY(this->EnsureInitialized());
return sm::UnregisterService(this->pid, service);
return impl::UnregisterService(this->pid, service);
}
Result UserService::AtmosphereInstallMitm(Out<MovedHandle> srv_h, Out<MovedHandle> qry_h, ServiceName service) {
R_TRY(this->EnsureInitialized());
return sm::InstallMitm(srv_h.GetHandlePointer(), qry_h.GetHandlePointer(), this->pid, service);
return impl::InstallMitm(srv_h.GetHandlePointer(), qry_h.GetHandlePointer(), this->pid, service);
}
Result UserService::AtmosphereUninstallMitm(ServiceName service) {
R_TRY(this->EnsureInitialized());
return sm::UninstallMitm(this->pid, service);
return impl::UninstallMitm(this->pid, service);
}
Result UserService::AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service) {
R_TRY(this->EnsureInitialized());
return sm::AcknowledgeMitmSession(client_pid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
return impl::AcknowledgeMitmSession(client_pid.GetPointer(), fwd_h.GetHandlePointer(), this->pid, service);
}
Result UserService::AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid) {
R_TRY(this->EnsureInitialized());
return sm::AssociatePidTidForMitm(pid, tid);
return impl::AssociatePidTidForMitm(pid, tid);
}
Result UserService::AtmosphereHasMitm(Out<bool> out, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::HasMitm(out.GetPointer(), service);
}
Result UserService::AtmosphereHasService(Out<bool> out, ServiceName service) {
R_TRY(this->EnsureInitialized());
return impl::HasService(out.GetPointer(), service);
}
}

View file

@ -17,7 +17,7 @@
#pragma once
#include <switch.h>
#include <stratosphere.hpp>
#include "sm_types.hpp"
#include <stratosphere/sm.hpp>
namespace sts::sm {
@ -35,6 +35,9 @@ namespace sts::sm {
AtmosphereUninstallMitm = 65001,
AtmosphereAssociatePidTidForMitm = 65002,
AtmosphereAcknowledgeMitmSession = 65003,
AtmosphereHasMitm = 65004,
AtmosphereHasService = 65100,
};
private:
u64 pid = InvalidProcessId;
@ -53,6 +56,9 @@ namespace sts::sm {
virtual Result AtmosphereUninstallMitm(ServiceName service);
virtual Result AtmosphereAssociatePidTidForMitm(u64 pid, u64 tid);
virtual Result AtmosphereAcknowledgeMitmSession(Out<u64> client_pid, Out<MovedHandle> fwd_h, ServiceName service);
virtual Result AtmosphereHasMitm(Out<bool> out, ServiceName service);
virtual Result AtmosphereHasService(Out<bool> out, ServiceName service);
public:
DEFINE_SERVICE_DISPATCH_TABLE {
MakeServiceCommandMeta<CommandId::Initialize, &UserService::Initialize>(),
@ -64,6 +70,9 @@ namespace sts::sm {
MakeServiceCommandMeta<CommandId::AtmosphereUninstallMitm, &UserService::AtmosphereUninstallMitm>(),
MakeServiceCommandMeta<CommandId::AtmosphereAssociatePidTidForMitm, &UserService::AtmosphereAssociatePidTidForMitm>(),
MakeServiceCommandMeta<CommandId::AtmosphereAcknowledgeMitmSession, &UserService::AtmosphereAcknowledgeMitmSession>(),
MakeServiceCommandMeta<CommandId::AtmosphereHasMitm, &UserService::AtmosphereHasMitm>(),
MakeServiceCommandMeta<CommandId::AtmosphereHasService, &UserService::AtmosphereHasService>(),
};
};