summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLéo Lam <leolino.lam@gmail.com>2017-04-25 20:00:28 +0200
committerGitHub <noreply@github.com>2017-04-25 20:00:28 +0200
commit4d52df150bfb20f4892d364f00e52944ec3d3473 (patch)
tree253d88643dc2ed82eaf5937c70af1523ee16a7d5 /Source/Core
parent7a615afe17df00dfa93e9e0dbd27bf743ff07068 (diff)
parentcc40389f88794d07b1f523f3627d6084e943d159 (diff)
Merge pull request #5317 from leoetlino/es-setuid
IOS/ES: Implement ES_SetUid
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/IOS/Device.cpp2
-rw-r--r--Source/Core/Core/IOS/Device.h4
-rw-r--r--Source/Core/Core/IOS/ES/ES.cpp40
-rw-r--r--Source/Core/Core/IOS/ES/ES.h3
-rw-r--r--Source/Core/Core/State.cpp2
5 files changed, 44 insertions, 7 deletions
diff --git a/Source/Core/Core/IOS/Device.cpp b/Source/Core/Core/IOS/Device.cpp
index cf01110caa..e93f867f83 100644
--- a/Source/Core/Core/IOS/Device.cpp
+++ b/Source/Core/Core/IOS/Device.cpp
@@ -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_)
diff --git a/Source/Core/Core/IOS/Device.h b/Source/Core/Core/IOS/Device.h
index 55d2d4a593..75df14a2a8 100644
--- a/Source/Core/Core/IOS/Device.h
+++ b/Source/Core/Core/IOS/Device.h
@@ -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);
};
diff --git a/Source/Core/Core/IOS/ES/ES.cpp b/Source/Core/Core/IOS/ES/ES.cpp
index ef3864bcf8..12b1c977db 100644
--- a/Source/Core/Core/IOS/ES/ES.cpp
+++ b/Source/Core/Core/IOS/ES/ES.cpp
@@ -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);
}
diff --git a/Source/Core/Core/IOS/ES/ES.h b/Source/Core/Core/IOS/ES/ES.h
index 9c49d7fcd7..e7cb5c6c45 100644
--- a/Source/Core/Core/IOS/ES/ES.h
+++ b/Source/Core/Core/IOS/ES/ES.h
@@ -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
diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
index 1d1f92cd2f..41a52669fc 100644
--- a/Source/Core/Core/State.cpp
+++ b/Source/Core/Core/State.cpp
@@ -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,