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