mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-22 20:06:40 +00:00
mitm: fix long-standing C descriptor issue.
This commit is contained in:
parent
bb223eb5ae
commit
e07011be32
9 changed files with 17 additions and 143 deletions
|
@ -18,7 +18,6 @@
|
|||
#include <algorithm>
|
||||
#include <switch.h>
|
||||
#include "set_mitm_service.hpp"
|
||||
#include "set_shim.h"
|
||||
|
||||
void SetMitmService::PostProcess(IMitmServiceObject *obj, IpcResponseContext *ctx) {
|
||||
/* No commands need postprocessing. */
|
||||
|
@ -104,7 +103,3 @@ Result SetMitmService::GetRegionCode(Out<u32> out_region_code) {
|
|||
out_region_code.SetValue(this->locale.region_code);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result SetMitmService::GetAvailableLanguageCodes(OutPointerWithClientSize<u64> out_language_codes, Out<s32> out_count) {
|
||||
return setGetAvailableLanguageCodesFwd(this->forward_service.get(), out_count.GetPointer(), out_language_codes.pointer, out_language_codes.num_elements);
|
||||
}
|
||||
|
|
|
@ -25,10 +25,6 @@ class SetMitmService : public IMitmServiceObject {
|
|||
enum class CommandId {
|
||||
GetLanguageCode = 0,
|
||||
GetRegionCode = 4,
|
||||
|
||||
/* Commands for which set:sys *must* act as a passthrough. */
|
||||
/* TODO: Solve the relevant IPC detection problem. */
|
||||
GetAvailableLanguageCodes = 1,
|
||||
};
|
||||
private:
|
||||
sts::os::Mutex lock;
|
||||
|
@ -55,14 +51,9 @@ class SetMitmService : public IMitmServiceObject {
|
|||
/* Overridden commands. */
|
||||
Result GetLanguageCode(Out<u64> out_lang_code);
|
||||
Result GetRegionCode(Out<u32> out_region_code);
|
||||
|
||||
/* Forced passthrough commands. */
|
||||
Result GetAvailableLanguageCodes(OutPointerWithClientSize<u64> out_language_codes, Out<s32> out_count);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetMitmService, GetLanguageCode),
|
||||
MAKE_SERVICE_COMMAND_META(SetMitmService, GetRegionCode),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(SetMitmService, GetAvailableLanguageCodes),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,59 +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/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <switch.h>
|
||||
#include "setsys_shim.h"
|
||||
|
||||
/* Command forwarders. */
|
||||
Result setGetAvailableLanguageCodesFwd(Service* s, s32 *total_entries, u64 *language_codes, size_t max_entries) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvStatic(&c, language_codes, max_entries * sizeof(*language_codes), 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 1;
|
||||
|
||||
Result rc = serviceIpcDispatch(s);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
s32 total_entries;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(s, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
*total_entries = resp->total_entries;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
/**
|
||||
* @file set_shim.h
|
||||
* @brief Settings Services (set) IPC wrapper. To be merged into libnx, eventually.
|
||||
* @author SciresM
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Command forwarders. */
|
||||
Result setGetAvailableLanguageCodesFwd(Service* s, s32 *total_entries, u64 *language_codes, size_t max_entries);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -98,7 +98,3 @@ Result SetSysMitmService::GetSettingsItemValue(Out<u64> out_size, OutBuffer<u8>
|
|||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result SetSysMitmService::GetEdid(OutPointerWithServerSize<SetSysEdid, 0x1> out) {
|
||||
return setsysGetEdidFwd(this->forward_service.get(), out.pointer);
|
||||
}
|
||||
|
|
|
@ -27,10 +27,6 @@ class SetSysMitmService : public IMitmServiceObject {
|
|||
GetFirmwareVersion2 = 4,
|
||||
GetSettingsItemValueSize = 37,
|
||||
GetSettingsItemValue = 38,
|
||||
|
||||
/* Commands for which set:sys *must* act as a passthrough. */
|
||||
/* TODO: Solve the relevant IPC detection problem. */
|
||||
GetEdid = 41,
|
||||
};
|
||||
public:
|
||||
SetSysMitmService(std::shared_ptr<Service> s, u64 pid, sts::ncm::TitleId tid) : IMitmServiceObject(s, pid, tid) {
|
||||
|
@ -50,16 +46,11 @@ class SetSysMitmService : public IMitmServiceObject {
|
|||
Result GetFirmwareVersion2(OutPointerWithServerSize<SetSysFirmwareVersion, 0x1> out);
|
||||
Result GetSettingsItemValueSize(Out<u64> out_size, InPointer<char> name, InPointer<char> key);
|
||||
Result GetSettingsItemValue(Out<u64> out_size, OutBuffer<u8> out_value, InPointer<char> name, InPointer<char> key);
|
||||
|
||||
/* Forced passthrough commands. */
|
||||
Result GetEdid(OutPointerWithServerSize<SetSysEdid, 0x1> out);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetFirmwareVersion),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetFirmwareVersion2),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetSettingsItemValueSize),
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetSettingsItemValue),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(SetSysMitmService, GetEdid),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -19,39 +19,6 @@
|
|||
#include "setsys_shim.h"
|
||||
|
||||
/* Command forwarders. */
|
||||
Result setsysGetEdidFwd(Service* s, SetSysEdid* out) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
ipcAddRecvStatic(&c, out, sizeof(*out), 0);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
} *raw;
|
||||
|
||||
raw = serviceIpcPrepareHeader(s, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 41;
|
||||
|
||||
Result rc = serviceIpcDispatch(s);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(s, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result setsysGetSettingsItemValueFwd(Service *s, const char *name, const char *item_key, void *value_out, size_t value_out_size, u64 *size_out) {
|
||||
char send_name[SET_MAX_NAME_SIZE];
|
||||
char send_item_key[SET_MAX_NAME_SIZE];
|
||||
|
|
|
@ -11,12 +11,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char edid[0x100];
|
||||
} SetSysEdid;
|
||||
|
||||
/* Command forwarders. */
|
||||
Result setsysGetEdidFwd(Service* s, SetSysEdid* out);
|
||||
Result setsysGetSettingsItemValueFwd(Service* s, const char *name, const char *item_key, void *value_out, size_t value_out_size, u64 *size_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -80,6 +80,23 @@ class MitmSession final : public ServiceSession {
|
|||
}
|
||||
|
||||
Result ForwardRequest(IpcResponseContext *ctx) {
|
||||
/* Mitm forward specific preprocessing. */
|
||||
if (ctx->request.NumStaticsOut) {
|
||||
u32 *cmdbuf = (u32 *)armGetTls();
|
||||
/* Overwrite the number of C descriptors to only use a single buffer. */
|
||||
cmdbuf[1] = (cmdbuf[1] & (~u32(0xF << 10))) | (0x2 << 10);
|
||||
|
||||
IpcStaticRecvDescriptor *c_desc = (IpcStaticRecvDescriptor *)(reinterpret_cast<uintptr_t>(ctx->request.RawWithoutPadding) + ctx->request.RawSize);
|
||||
/* Don't write out of bounds, though this should never happen. */
|
||||
if (reinterpret_cast<uintptr_t>(c_desc) + sizeof(*c_desc) <= reinterpret_cast<uintptr_t>(cmdbuf) + 0x100) {
|
||||
uintptr_t ptr = reinterpret_cast<uintptr_t>(this->pointer_buffer.data());
|
||||
c_desc->Addr = ptr;
|
||||
c_desc->Packed = (ptr >> 32) | (this->pointer_buffer.size() << 16);
|
||||
} else {
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispatch forwards. */
|
||||
R_TRY(serviceIpcDispatch(this->forward_service.get()));
|
||||
|
||||
|
|
Loading…
Reference in a new issue