mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 15:49:25 +01:00
IOS: Implement UID/GID changes for the PPC
This will be required for permission checks in the future. Note that this is only for the PPC as we do not have actual processes. Keeping track of other modules' UIDs/GIDs is virtually useless anyway. UID/GID changes are implemented in the following functions: * ES_Launch * ES_DIVerify ES_SetUid is not implemented yet because it'd need further changes.
This commit is contained in:
parent
8a559f2e58
commit
dae950ff90
@ -158,6 +158,21 @@ IPCCommandResult ES::GetTitleID(const IOCtlVRequest& request)
|
||||
return GetDefaultReply(IPC_SUCCESS);
|
||||
}
|
||||
|
||||
static bool UpdateUIDAndGID(const IOS::ES::TMDReader& tmd)
|
||||
{
|
||||
IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_SESSION_ROOT};
|
||||
const u64 title_id = tmd.GetTitleId();
|
||||
const u32 uid = uid_sys.GetOrInsertUIDForTitle(title_id);
|
||||
if (!uid)
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "Failed to get UID for title %016" PRIx64, title_id);
|
||||
return false;
|
||||
}
|
||||
SetUIDForPPC(uid);
|
||||
SetGIDForPPC(tmd.GetGroupId());
|
||||
return true;
|
||||
}
|
||||
|
||||
IPCCommandResult ES::SetUID(const IOCtlVRequest& request)
|
||||
{
|
||||
if (!request.HasNumberOfValidVectors(1, 0))
|
||||
@ -226,6 +241,16 @@ bool ES::LaunchPPCTitle(u64 title_id, bool skip_reload)
|
||||
s_title_context.Update(content_loader);
|
||||
INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: %016" PRIx64,
|
||||
s_title_context.tmd.GetTitleId());
|
||||
|
||||
// Note: the UID/GID is also updated for IOS titles, but since we have no guarantee IOS titles
|
||||
// are installed, we can only do this for PPC titles.
|
||||
if (!UpdateUIDAndGID(s_title_context.tmd))
|
||||
{
|
||||
s_title_context.Clear();
|
||||
INFO_LOG(IOS_ES, "LaunchPPCTitle: Title context changed: (none)");
|
||||
return false;
|
||||
}
|
||||
|
||||
return BootstrapPPC(content_loader);
|
||||
}
|
||||
|
||||
@ -533,6 +558,9 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic
|
||||
if (tmd.GetTitleId() != ticket.GetTitleId())
|
||||
return ES_EINVAL;
|
||||
|
||||
s_title_context.Update(tmd, ticket);
|
||||
INFO_LOG(IOS_ES, "ES_DIVerify: Title context changed: %016" PRIx64, tmd.GetTitleId());
|
||||
|
||||
std::string tmd_path = Common::GetTMDFileName(tmd.GetTitleId(), Common::FROM_SESSION_ROOT);
|
||||
|
||||
File::CreateFullPath(tmd_path);
|
||||
@ -545,14 +573,15 @@ s32 ES::DIVerify(const IOS::ES::TMDReader& tmd, const IOS::ES::TicketReader& tic
|
||||
if (!tmd_file.WriteBytes(tmd_bytes.data(), tmd_bytes.size()))
|
||||
ERROR_LOG(IOS_ES, "DIVerify failed to write disc TMD to NAND.");
|
||||
}
|
||||
IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_SESSION_ROOT};
|
||||
uid_sys.AddTitle(tmd.GetTitleId());
|
||||
// DI_VERIFY writes to title.tmd, which is read and cached inside the NAND Content Manager.
|
||||
// clear the cache to avoid content access mismatches.
|
||||
DiscIO::CNANDContentManager::Access().ClearCache();
|
||||
|
||||
s_title_context.Update(tmd, ticket);
|
||||
INFO_LOG(IOS_ES, "ES_DIVerify: Title context changed: %016" PRIx64, tmd.GetTitleId());
|
||||
if (!UpdateUIDAndGID(s_title_context.tmd))
|
||||
{
|
||||
return ES_SHORT_READ;
|
||||
}
|
||||
|
||||
return IPC_SUCCESS;
|
||||
}
|
||||
} // namespace Device
|
||||
|
@ -446,11 +446,11 @@ UIDSys::UIDSys(Common::FromWhichRoot root)
|
||||
|
||||
if (m_entries.empty())
|
||||
{
|
||||
AddTitle(TITLEID_SYSMENU);
|
||||
GetOrInsertUIDForTitle(TITLEID_SYSMENU);
|
||||
}
|
||||
}
|
||||
|
||||
u32 UIDSys::GetUIDFromTitle(u64 title_id)
|
||||
u32 UIDSys::GetUIDFromTitle(u64 title_id) const
|
||||
{
|
||||
const auto it = std::find_if(m_entries.begin(), m_entries.end(),
|
||||
[title_id](const auto& entry) { return entry.second == title_id; });
|
||||
@ -464,26 +464,33 @@ u32 UIDSys::GetNextUID() const
|
||||
return m_entries.rbegin()->first + 1;
|
||||
}
|
||||
|
||||
void UIDSys::AddTitle(u64 title_id)
|
||||
u32 UIDSys::GetOrInsertUIDForTitle(const u64 title_id)
|
||||
{
|
||||
if (GetUIDFromTitle(title_id))
|
||||
const u32 current_uid = GetUIDFromTitle(title_id);
|
||||
if (current_uid)
|
||||
{
|
||||
INFO_LOG(IOS_ES, "Title %016" PRIx64 " already exists in uid.sys", title_id);
|
||||
return;
|
||||
return current_uid;
|
||||
}
|
||||
|
||||
u32 uid = GetNextUID();
|
||||
const u32 uid = GetNextUID();
|
||||
m_entries.insert({uid, title_id});
|
||||
|
||||
// Byte swap before writing.
|
||||
title_id = Common::swap64(title_id);
|
||||
uid = Common::swap32(uid);
|
||||
const u64 swapped_title_id = Common::swap64(title_id);
|
||||
const u32 swapped_uid = Common::swap32(uid);
|
||||
|
||||
File::CreateFullPath(m_file_path);
|
||||
File::IOFile file(m_file_path, "ab");
|
||||
|
||||
if (!file.WriteBytes(&title_id, sizeof(title_id)) || !file.WriteBytes(&uid, sizeof(uid)))
|
||||
if (!file.WriteBytes(&swapped_title_id, sizeof(title_id)) ||
|
||||
!file.WriteBytes(&swapped_uid, sizeof(uid)))
|
||||
{
|
||||
ERROR_LOG(IOS_ES, "Failed to write to /sys/uid.sys");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return uid;
|
||||
}
|
||||
} // namespace ES
|
||||
} // namespace IOS
|
||||
|
@ -219,8 +219,8 @@ class UIDSys final
|
||||
public:
|
||||
explicit UIDSys(Common::FromWhichRoot root);
|
||||
|
||||
u32 GetUIDFromTitle(u64 title_id);
|
||||
void AddTitle(u64 title_id);
|
||||
u32 GetUIDFromTitle(u64 title_id) const;
|
||||
u32 GetOrInsertUIDForTitle(u64 title_id);
|
||||
u32 GetNextUID() const;
|
||||
|
||||
private:
|
||||
|
@ -194,7 +194,7 @@ bool InitImport(u64 title_id)
|
||||
}
|
||||
|
||||
UIDSys uid_sys{Common::FROM_CONFIGURED_ROOT};
|
||||
uid_sys.AddTitle(title_id);
|
||||
uid_sys.GetOrInsertUIDForTitle(title_id);
|
||||
|
||||
// IOS moves the title content directory to /import if the TMD exists during an import.
|
||||
if (File::Exists(Common::GetTMDFileName(title_id, Common::FROM_SESSION_ROOT)))
|
||||
|
@ -91,6 +91,9 @@ static u64 s_last_reply_time;
|
||||
|
||||
static u64 s_active_title_id;
|
||||
|
||||
static u32 s_ppc_uid;
|
||||
static u16 s_ppc_gid;
|
||||
|
||||
static constexpr u64 ENQUEUE_REQUEST_FLAG = 0x100000000ULL;
|
||||
static constexpr u64 ENQUEUE_ACKNOWLEDGEMENT_FLAG = 0x200000000ULL;
|
||||
|
||||
@ -702,6 +705,28 @@ bool Reload(const u64 ios_title_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Since we don't have actual processes, we keep track of only the PPC's UID/GID.
|
||||
// These functions roughly correspond to syscalls 0x2b, 0x2c, 0x2d, 0x2e (though only for the PPC).
|
||||
void SetUIDForPPC(u32 uid)
|
||||
{
|
||||
s_ppc_uid = uid;
|
||||
}
|
||||
|
||||
u32 GetUIDForPPC()
|
||||
{
|
||||
return s_ppc_uid;
|
||||
}
|
||||
|
||||
void SetGIDForPPC(u16 gid)
|
||||
{
|
||||
s_ppc_gid = gid;
|
||||
}
|
||||
|
||||
u16 GetGIDForPPC()
|
||||
{
|
||||
return s_ppc_gid;
|
||||
}
|
||||
|
||||
// This corresponds to syscall 0x41, which loads a binary from the NAND and bootstraps the PPC.
|
||||
// Unlike 0x42, IOS will set up some constants in memory before booting the PPC.
|
||||
bool BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader)
|
||||
@ -783,6 +808,8 @@ void DoState(PointerWrap& p)
|
||||
p.Do(s_reply_queue);
|
||||
p.Do(s_last_reply_time);
|
||||
p.Do(s_active_title_id);
|
||||
p.Do(s_ppc_uid);
|
||||
p.Do(s_ppc_gid);
|
||||
|
||||
if (s_active_title_id == MIOS_TITLE_ID)
|
||||
return;
|
||||
|
@ -59,6 +59,11 @@ void Shutdown();
|
||||
bool Reload(u64 ios_title_id);
|
||||
u32 GetVersion();
|
||||
|
||||
void SetUIDForPPC(u32 uid);
|
||||
u32 GetUIDForPPC();
|
||||
void SetGIDForPPC(u16 gid);
|
||||
u16 GetGIDForPPC();
|
||||
|
||||
bool BootstrapPPC(const DiscIO::CNANDContentLoader& content_loader);
|
||||
|
||||
// Do State
|
||||
|
@ -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 = 79; // Last changed in PR 4981
|
||||
static const u32 STATE_VERSION = 80; // Last changed in PR 5309
|
||||
|
||||
// Maps savestate versions to Dolphin versions.
|
||||
// Versions after 42 don't need to be added to this list,
|
||||
|
@ -336,7 +336,7 @@ u64 CNANDContentManager::Install_WiiWAD(const std::string& filename)
|
||||
}
|
||||
|
||||
IOS::ES::UIDSys uid_sys{Common::FromWhichRoot::FROM_CONFIGURED_ROOT};
|
||||
uid_sys.AddTitle(title_id);
|
||||
uid_sys.GetOrInsertUIDForTitle(title_id);
|
||||
|
||||
ClearCache();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user