Skip to content

Commit

Permalink
IOS HLE: Prevent accessing host file system
Browse files Browse the repository at this point in the history
  • Loading branch information
JosJuice committed Nov 12, 2016
1 parent 536d4ef commit 3688244
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
15 changes: 14 additions & 1 deletion Source/Core/Common/FileUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <cstring>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
#include <string>
#include <sys/stat.h>
#include <vector>
Expand All @@ -30,7 +31,6 @@
#include <dirent.h>
#include <errno.h>
#include <libgen.h>
#include <stdlib.h>
#include <unistd.h>
#endif

Expand Down Expand Up @@ -712,6 +712,19 @@ std::string GetBundleDirectory()
}
#endif

std::string GetAbsolutePath(const std::string& path)
{
#ifdef _WIN32
wchar_t absolute_path[_MAX_PATH];
wchar_t* result = _wfullpath(absolute_path, UTF8ToTStr(path).c_str(), _MAX_PATH);
return result ? TStrToUTF8(result) : "";
#else
char absolute_path[MAX_PATH + 1];
char* result = realpath(path.c_str(), absolute_path);
return result ? std::string(result) : "";
#endif
}

std::string& GetExeDirectory()
{
static std::string DolphinPath;
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/Common/FileUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ std::string CreateTempDir();
// Get a filename that can hopefully be atomically renamed to the given path.
std::string GetTempFilenameForAtomicWrite(const std::string& path);

// Converts the given path into an absolute path.
// An empty string is returned if an error occurs.
std::string GetAbsolutePath(const std::string& path);

// Gets a set user directory path
// Don't call prior to setting the base user directory
const std::string& GetUserPath(unsigned int dir_index);
Expand Down
28 changes: 24 additions & 4 deletions Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,38 @@ static std::map<std::string, std::weak_ptr<File::IOFile>> openFiles;
// This is used by several of the FileIO and /dev/fs functions
std::string HLE_IPC_BuildFilename(std::string path_wii)
{
std::string path_full = File::GetUserPath(D_SESSION_WIIROOT_IDX);

// Replaces chars that FAT32 can't support with strings defined in /sys/replace
for (auto& replacement : replacements)
{
for (size_t j = 0; (j = path_wii.find(replacement.first, j)) != path_wii.npos; ++j)
path_wii.replace(j, 1, replacement.second);
}

path_full += path_wii;
const std::string root_path = File::GetUserPath(D_SESSION_WIIROOT_IDX);
const std::string full_path = root_path + path_wii;

return path_full;
// Prevent the emulated system from accessing files that aren't in the NAND directory.
// (Software that tries to exploit Dolphin might access a path like "/../..".)
const std::string absolute_root_path = File::GetAbsolutePath(root_path);
const std::string absolute_full_path = File::GetAbsolutePath(full_path);
if (absolute_root_path.empty() || absolute_full_path.empty())
{
PanicAlert("Couldn't get an absolute path. The root directory will be returned. "
"This will most likely will lead to failures.");
return root_path;
}
else if (path_wii.empty() || path_wii[0] != '/' ||
absolute_full_path.compare(0, absolute_root_path.size(), absolute_root_path) != 0)
{
WARN_LOG(WII_IPC_FILEIO,
"The emulated software tried to access a file outside of the NAND directory: %s",
absolute_full_path.c_str());
return root_path;
}
else
{
return full_path;
}
}

void HLE_IPC_CreateVirtualFATFilesystem()
Expand Down

0 comments on commit 3688244

Please sign in to comment.