mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-11 15:09:00 +01:00
Merge pull request #5317 from leoetlino/es-setuid
IOS/ES: Implement ES_SetUid
This commit is contained in:
commit
4d52df150b
@ -26,6 +26,8 @@ OpenRequest::OpenRequest(const u32 address_) : Request(address_)
|
|||||||
{
|
{
|
||||||
path = Memory::GetString(Memory::Read_U32(address + 0xc));
|
path = Memory::GetString(Memory::Read_U32(address + 0xc));
|
||||||
flags = static_cast<OpenMode>(Memory::Read_U32(address + 0x10));
|
flags = static_cast<OpenMode>(Memory::Read_U32(address + 0x10));
|
||||||
|
uid = GetUIDForPPC();
|
||||||
|
gid = GetGIDForPPC();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadWriteRequest::ReadWriteRequest(const u32 address_) : Request(address_)
|
ReadWriteRequest::ReadWriteRequest(const u32 address_) : Request(address_)
|
||||||
|
@ -92,6 +92,10 @@ struct OpenRequest final : Request
|
|||||||
{
|
{
|
||||||
std::string path;
|
std::string path;
|
||||||
OpenMode flags = IOS_OPEN_READ;
|
OpenMode flags = IOS_OPEN_READ;
|
||||||
|
// The UID and GID are not part of the IPC request sent from the PPC to the Starlet,
|
||||||
|
// but they are set after they reach IOS and are dispatched to the appropriate module.
|
||||||
|
u32 uid = 0;
|
||||||
|
u16 gid = 0;
|
||||||
explicit OpenRequest(u32 address);
|
explicit OpenRequest(u32 address);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -173,14 +173,39 @@ static bool UpdateUIDAndGID(const IOS::ES::TMDReader& tmd)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ReturnCode CheckIsAllowedToSetUID(const u32 caller_uid)
|
||||||
|
{
|
||||||
|
IOS::ES::UIDSys uid_map{Common::FromWhichRoot::FROM_SESSION_ROOT};
|
||||||
|
const u32 system_menu_uid = uid_map.GetOrInsertUIDForTitle(TITLEID_SYSMENU);
|
||||||
|
if (!system_menu_uid)
|
||||||
|
return ES_SHORT_READ;
|
||||||
|
return caller_uid == system_menu_uid ? IPC_SUCCESS : ES_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
IPCCommandResult ES::SetUID(const IOCtlVRequest& request)
|
IPCCommandResult ES::SetUID(const IOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
if (!request.HasNumberOfValidVectors(1, 0))
|
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != 8)
|
||||||
return GetDefaultReply(ES_EINVAL);
|
return GetDefaultReply(ES_EINVAL);
|
||||||
|
|
||||||
// TODO: fs permissions based on this
|
const u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
|
||||||
u64 TitleID = Memory::Read_U64(request.in_vectors[0].address);
|
|
||||||
INFO_LOG(IOS_ES, "IOCTL_ES_SETUID titleID: %08x/%08x", (u32)(TitleID >> 32), (u32)TitleID);
|
const s32 ret = CheckIsAllowedToSetUID(m_caller_uid);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
ERROR_LOG(IOS_ES, "SetUID: Permission check failed with error %d", ret);
|
||||||
|
return GetDefaultReply(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto tmd = IOS::ES::FindInstalledTMD(title_id);
|
||||||
|
if (!tmd.IsValid())
|
||||||
|
return GetDefaultReply(FS_ENOENT);
|
||||||
|
|
||||||
|
if (!UpdateUIDAndGID(tmd))
|
||||||
|
{
|
||||||
|
ERROR_LOG(IOS_ES, "SetUID: Failed to get UID for title %016" PRIx64, title_id);
|
||||||
|
return GetDefaultReply(ES_SHORT_READ);
|
||||||
|
}
|
||||||
|
|
||||||
return GetDefaultReply(IPC_SUCCESS);
|
return GetDefaultReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,6 +290,9 @@ void ES::DoState(PointerWrap& p)
|
|||||||
p.Do(m_addtitle_content_id);
|
p.Do(m_addtitle_content_id);
|
||||||
p.Do(m_addtitle_content_buffer);
|
p.Do(m_addtitle_content_buffer);
|
||||||
|
|
||||||
|
p.Do(m_caller_uid);
|
||||||
|
p.Do(m_caller_gid);
|
||||||
|
|
||||||
p.Do(m_export_title_context.valid);
|
p.Do(m_export_title_context.valid);
|
||||||
m_export_title_context.tmd.DoState(p);
|
m_export_title_context.tmd.DoState(p);
|
||||||
p.Do(m_export_title_context.title_key);
|
p.Do(m_export_title_context.title_key);
|
||||||
@ -296,8 +324,8 @@ void ES::DoState(PointerWrap& p)
|
|||||||
|
|
||||||
ReturnCode ES::Open(const OpenRequest& request)
|
ReturnCode ES::Open(const OpenRequest& request)
|
||||||
{
|
{
|
||||||
if (m_is_active)
|
m_caller_uid = request.uid;
|
||||||
INFO_LOG(IOS_ES, "Device was re-opened.");
|
m_caller_gid = request.gid;
|
||||||
return Device::Open(request);
|
return Device::Open(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,6 +246,9 @@ private:
|
|||||||
u32 m_addtitle_content_id = 0xFFFFFFFF;
|
u32 m_addtitle_content_id = 0xFFFFFFFF;
|
||||||
std::vector<u8> m_addtitle_content_buffer;
|
std::vector<u8> m_addtitle_content_buffer;
|
||||||
|
|
||||||
|
u32 m_caller_uid = 0;
|
||||||
|
u16 m_caller_gid = 0;
|
||||||
|
|
||||||
struct TitleExportContext
|
struct TitleExportContext
|
||||||
{
|
{
|
||||||
struct ExportContent
|
struct ExportContent
|
||||||
|
@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
|||||||
static std::thread g_save_thread;
|
static std::thread g_save_thread;
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
static const u32 STATE_VERSION = 80; // Last changed in PR 5309
|
static const u32 STATE_VERSION = 81; // Last changed in PR 5317
|
||||||
|
|
||||||
// Maps savestate versions to Dolphin versions.
|
// Maps savestate versions to Dolphin versions.
|
||||||
// Versions after 42 don't need to be added to this list,
|
// Versions after 42 don't need to be added to this list,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user