Merge pull request #5317 from leoetlino/es-setuid

IOS/ES: Implement ES_SetUid
This commit is contained in:
Léo Lam 2017-04-25 20:00:28 +02:00 committed by GitHub
commit 4d52df150b
5 changed files with 44 additions and 7 deletions

View file

@ -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_)

View file

@ -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);
}; };

View file

@ -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);
} }

View file

@ -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

View file

@ -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,