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:
parent
c01fda6255
commit
cc40389f88
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue