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));
flags = static_cast<OpenMode>(Memory::Read_U32(address + 0x10));
uid = GetUIDForPPC();
gid = GetGIDForPPC();
}
ReadWriteRequest::ReadWriteRequest(const u32 address_) : Request(address_)

View file

@ -92,6 +92,10 @@ struct OpenRequest final : Request
{
std::string path;
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);
};

View file

@ -173,14 +173,39 @@ static bool UpdateUIDAndGID(const IOS::ES::TMDReader& tmd)
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)
{
if (!request.HasNumberOfValidVectors(1, 0))
if (!request.HasNumberOfValidVectors(1, 0) || request.in_vectors[0].size != 8)
return GetDefaultReply(ES_EINVAL);
// TODO: fs permissions based on this
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 u64 title_id = Memory::Read_U64(request.in_vectors[0].address);
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);
}
@ -265,6 +290,9 @@ void ES::DoState(PointerWrap& p)
p.Do(m_addtitle_content_id);
p.Do(m_addtitle_content_buffer);
p.Do(m_caller_uid);
p.Do(m_caller_gid);
p.Do(m_export_title_context.valid);
m_export_title_context.tmd.DoState(p);
p.Do(m_export_title_context.title_key);
@ -296,8 +324,8 @@ void ES::DoState(PointerWrap& p)
ReturnCode ES::Open(const OpenRequest& request)
{
if (m_is_active)
INFO_LOG(IOS_ES, "Device was re-opened.");
m_caller_uid = request.uid;
m_caller_gid = request.gid;
return Device::Open(request);
}

View file

@ -246,6 +246,9 @@ private:
u32 m_addtitle_content_id = 0xFFFFFFFF;
std::vector<u8> m_addtitle_content_buffer;
u32 m_caller_uid = 0;
u16 m_caller_gid = 0;
struct TitleExportContext
{
struct ExportContent

View file

@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread;
// 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.
// Versions after 42 don't need to be added to this list,