IOS/ES: Implement ES_SetUid

This implements ES_SetUid, which is used by the system menu to change
its own permissions. This is required for implementing permission
checks and proper NAND metadata support in the future.
This commit is contained in:
Léo Lam 2017-04-25 00:07:34 +02:00
parent c01fda6255
commit cc40389f88
3 changed files with 38 additions and 7 deletions

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,