Skip to content
23 changes: 23 additions & 0 deletions src/core/libraries/kernel/file_system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,27 @@ s32 PS4_SYSV_ABI sceKernelRmdir(const char* path) {
return result;
}

s32 PS4_SYSV_ABI posix_access(const char* path, s32 mode) {
LOG_INFO(Kernel_Fs, "(PARTIAL) path = {}, mode = {}", path, mode);
if (strlen(path) > 255) {
*__Error() = POSIX_ENAMETOOLONG;
return -1;
}

auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
const bool is_dir = mnt->IsDirectory(path);
const bool is_file = !is_dir && mnt->Exists(path);
const bool is_root = strncmp(path, "/", 2) == 0;
if (!is_dir && !is_file && !is_root) {
*__Error() = POSIX_ENOENT;
return -1;
}
if (is_root) {
LOG_WARNING(Kernel_Fs, "Checking accessibility of filesystem root");
}
return ORBIS_OK;
}
Comment thread
StevenMiller123 marked this conversation as resolved.

s32 PS4_SYSV_ABI posix_stat(const char* path, OrbisKernelStat* sb) {
LOG_DEBUG(Kernel_Fs, "(PARTIAL) path = {}", path);
if (strlen(path) > 255) {
Expand Down Expand Up @@ -1562,6 +1583,8 @@ void RegisterFileSystem(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("c7ZnT7V1B98", "libScePosix", 1, "libkernel", posix_rmdir);
LIB_FUNCTION("c7ZnT7V1B98", "libkernel", 1, "libkernel", posix_rmdir);
LIB_FUNCTION("naInUjYt3so", "libkernel", 1, "libkernel", sceKernelRmdir);
LIB_FUNCTION("8vE6Z6VEYyk", "libkernel_psmkit", 1, "libkernel", posix_access);
LIB_FUNCTION("8vE6Z6VEYyk", "libkernel", 1, "libkernel", posix_access);
LIB_FUNCTION("E6ao34wPw+U", "libScePosix", 1, "libkernel", posix_stat);
LIB_FUNCTION("E6ao34wPw+U", "libkernel", 1, "libkernel", posix_stat);
LIB_FUNCTION("eV9wAD2riIA", "libkernel", 1, "libkernel", sceKernelStat);
Expand Down
1 change: 1 addition & 0 deletions src/core/libraries/kernel/file_system.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ constexpr int ORBIS_KERNEL_O_DIRECTORY = 0x00020000;
s32 PS4_SYSV_ABI posix_open(const char* path, s32 flags, u16 mode);
s32 PS4_SYSV_ABI posix_close(s32 fd);
s64 PS4_SYSV_ABI posix_lseek(s32 fd, s64 offset, s32 whence);
s32 PS4_SYSV_ABI posix_access(const char* path, s32 mode);
s64 PS4_SYSV_ABI sceKernelWrite(s32 fd, const void* buf, u64 nbytes);
s64 PS4_SYSV_ABI sceKernelRead(s32 fd, void* buf, u64 nbytes);
s64 PS4_SYSV_ABI sceKernelPread(s32 fd, void* buf, u64 nbytes, s64 offset);
Expand Down
6 changes: 5 additions & 1 deletion src/core/libraries/kernel/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ void* PS4_SYSV_ABI sceKernelGetProcParam() {
s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, u64 args, const void* argp,
u32 flags, const void* pOpt, s32* pRes) {
LOG_INFO(Lib_Kernel, "called filename = {}, args = {}", moduleFileName, args);
ASSERT(flags == 0);
if (flags != 0) {
LOG_ERROR(Lib_Kernel, "unhandled flags: {:#x}", flags);
}

auto* linker = Common::Singleton<Core::Linker>::Instance();

Expand Down Expand Up @@ -293,6 +295,8 @@ void RegisterProcess(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("g0VTBxfJyu0", "libkernel", 1, "libkernel", sceKernelGetCurrentCpu);
LIB_FUNCTION("959qrazPIrg", "libkernel", 1, "libkernel", sceKernelGetProcParam);
LIB_FUNCTION("wzvqT4UqKX8", "libkernel", 1, "libkernel", sceKernelLoadStartModule);
LIB_FUNCTION("Y1nEpkCieOY", "libkernel", 1, "libkernel",
sceKernelLoadStartModule); // sceKernelLoadStartModuleInternalForMono
LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", sceKernelDlsym);
LIB_FUNCTION("RpQJJVKTiFM", "libkernel", 1, "libkernel", sceKernelGetModuleInfoForUnwind);
LIB_FUNCTION("f7KBOafysXo", "libkernel", 1, "libkernel", sceKernelGetModuleInfoFromAddr);
Expand Down
3 changes: 3 additions & 0 deletions src/core/libraries/kernel/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ s32 PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(s32* ver);
s32 PS4_SYSV_ABI sceKernelGetModuleInfoForUnwind(VAddr addr, s32 flags,
OrbisModuleInfoForUnwind* info);

s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, u64 args, const void* argp,
u32 flags, const void* pOpt, s32* pRes);

void RegisterProcess(Core::Loader::SymbolsResolver* sym);

} // namespace Libraries::Kernel
21 changes: 18 additions & 3 deletions src/core/libraries/sysmodule/sysmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "common/elf_info.h"
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/kernel/file_system.h"
#include "core/libraries/kernel/kernel.h"
#include "core/libraries/kernel/orbis_error.h"
#include "core/libraries/kernel/process.h"
#include "core/libraries/libs.h"
Expand Down Expand Up @@ -98,9 +100,22 @@ s32 PS4_SYSV_ABI sceSysmoduleLoadModule(OrbisSysModule id) {
return result;
}

s32 PS4_SYSV_ABI sceSysmoduleLoadModuleByNameInternal() {
LOG_ERROR(Lib_SysModule, "(STUBBED) called");
return ORBIS_OK;
s32 PS4_SYSV_ABI sceSysmoduleLoadModuleByNameInternal(char const* name, u64 args, void const* argp,
void const* popt, s32* res) {
LOG_ERROR(Lib_SysModule, "(DUMMY) called, name: {}", name);
std::string filename = std::string(name) + ".sprx";
s32 exists;
using namespace Kernel;
std::string system_base = std::string("/") + sceKernelGetFsSandboxRandomWord();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally think we should tie this into some allow/block list instead of relying on users making game-specific module folders for things calling this (even if it's only called by firmware stuff).
Maybe try to have this use the same array of allowed modules that's currently placed in the loadModule code, with a bypass for modules present in game-specific module folders?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine by me, do you have a list of safely LLEable modules loaded through this function perchance?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Been too long since I glanced at VSH, I forget what all it tries loading through this.

exists = posix_access((system_base + "/common/lib/" + filename).c_str(), 0);
if (exists == 0)
return sceKernelLoadStartModule((system_base + "/common/lib/" + filename).c_str(), args,
argp, 0, popt, res);
exists = posix_access((system_base + "/priv/lib/" + filename).c_str(), 0);
if (exists == 0)
return sceKernelLoadStartModule((system_base + "/priv/lib/" + filename).c_str(), args, argp,
0, popt, res);
return ORBIS_KERNEL_ERROR_EINVAL;
}

s32 PS4_SYSV_ABI sceSysmoduleLoadModuleInternal(OrbisSysModuleInternal id) {
Expand Down
3 changes: 2 additions & 1 deletion src/core/libraries/sysmodule/sysmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ s32 PS4_SYSV_ABI sceSysmoduleIsCameraPreloaded();
s32 PS4_SYSV_ABI sceSysmoduleIsLoaded(OrbisSysModule id);
s32 PS4_SYSV_ABI sceSysmoduleIsLoadedInternal(OrbisSysModuleInternal id);
s32 PS4_SYSV_ABI sceSysmoduleLoadModule(OrbisSysModule id);
s32 PS4_SYSV_ABI sceSysmoduleLoadModuleByNameInternal();
s32 PS4_SYSV_ABI sceSysmoduleLoadModuleByNameInternal(char const* name, u64 args, void const* argp,
void const* popt, s32* res);
s32 PS4_SYSV_ABI sceSysmoduleLoadModuleInternal(OrbisSysModuleInternal id);
s32 PS4_SYSV_ABI sceSysmoduleLoadModuleInternalWithArg(OrbisSysModuleInternal id, s32 argc,
const void* argv, u64 unk, s32* res_out);
Expand Down
10 changes: 10 additions & 0 deletions src/emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,16 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
}
mnt->Mount(host_font2_dir, guest_font_dir);

if (!id.empty() && std::filesystem::exists(EmulatorSettings.GetSysModulesDir() / id)) {
mnt->Mount(EmulatorSettings.GetSysModulesDir() / id,
std::string("/") + sandbox_root + "/common/lib/");
mnt->Mount(EmulatorSettings.GetSysModulesDir() / id,
std::string("/") + sandbox_root + "/priv/lib/");
// should be empty but whatever
mnt->Mount(EmulatorSettings.GetSysModulesDir() / id,
std::string("/") + sandbox_root + "/common_ex/lib/");
}

if (std::filesystem::is_empty(host_font_dir) || std::filesystem::is_empty(host_font2_dir)) {
LOG_WARNING(Loader, "No dumped system fonts, expect missing text or instability");
}
Expand Down
Loading