Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions core/libs/prx/libkernel/System/src/SystemConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ int APS5_VABI sysctl_nid_postfix(const int* name, std::uint32_t nameLength, void
throw std::runtime_error(std::string(__func__) + ": unsupported MIB " + mib);
}

uint64_t APS5_VABI sceKernelGetTscFrequency(void);

int APS5_VABI sysctlbyname_nid_postfix(const char* name, void* oldValue, std::size_t* oldLength, const void* newValue, std::size_t newLength) {
if (name == nullptr) {
*__error_nid_postfix() = 14;
Expand Down Expand Up @@ -202,6 +204,11 @@ int APS5_VABI sysctlbyname_nid_postfix(const char* name, void* oldValue, std::si
for (std::size_t i = 0; i < *oldLength; ++i) bytes[i] = static_cast<std::uint8_t>(device());
return 0;
}
if (std::strcmp(name, "machdep.tsc_freq") == 0) {
if (newValue != nullptr) throw std::runtime_error(std::string(__func__) + ": setting machdep.tsc_freq");
const std::uint64_t frequency = sceKernelGetTscFrequency();
return CopyOut(&frequency, sizeof(frequency), oldValue, oldLength);
}
if (std::strcmp(name, "kern.sdk_version") == 0) {
if (newValue != nullptr) {
*__error_nid_postfix() = 1;
Expand Down
24 changes: 24 additions & 0 deletions core/libs/tests/GuestSystemConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ int APS5_VABI sysctl_nid_postfix(const int*, std::uint32_t, void*, std::size_t*,
int APS5_VABI sysctlbyname_nid_postfix(const char*, void*, std::size_t*, const void*, std::size_t);
int APS5_VABI sceKernelGetSystemSwVersion_nid_postfix(SceKernelSystemSwVersion*);
int APS5_VABI getpid_nid_postfix();
std::uint64_t APS5_VABI sceKernelGetTscFrequency(void);
extern char** environ_nid_postfix;
}
static void Require(bool value) { if (!value) std::abort(); }
Expand Down Expand Up @@ -199,6 +200,28 @@ static void CheckPseudoRandomSysctl() {
}
Require(threw);
}
static void CheckTscFrequencySysctl() {
*__error_nid_postfix() = 13;
std::size_t length = 0;
Require(sysctlbyname_nid_postfix("machdep.tsc_freq", nullptr, &length, nullptr, 0) == 0 && length == sizeof(std::uint64_t));
std::uint64_t frequency = 0;
length = sizeof(frequency);
Require(sysctlbyname_nid_postfix("machdep.tsc_freq", &frequency, &length, nullptr, 0) == 0 && length == sizeof(std::uint64_t));
Require(frequency != 0 && frequency == sceKernelGetTscFrequency());
Require(*__error_nid_postfix() == 13);
unsigned char bytes[8] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
length = 4;
Require(sysctlbyname_nid_postfix("machdep.tsc_freq", bytes, &length, nullptr, 0) == -1 && *__error_nid_postfix() == 12);
Require(length == 4 && bytes[4] == 0xaa && bytes[7] == 0xaa);
bool threw = false;
length = sizeof(frequency);
try {
sysctlbyname_nid_postfix("machdep.tsc_freq", &frequency, &length, &frequency, sizeof(frequency));
} catch (const std::runtime_error&) {
threw = true;
}
Require(threw);
}
static void CheckSdkVersionSysctl() {
*__error_nid_postfix() = 13;
std::size_t length = 0;
Expand Down Expand Up @@ -260,6 +283,7 @@ int main() {
CheckSystemSwVersion();
CheckPseudoRandomSysctl();
CheckSdkVersionSysctl();
CheckTscFrequencySysctl();
CheckArandomSysctl();
*__error_nid_postfix() = 13;
Require(sysconf_nid_postfix(47) == 0x4000);
Expand Down
1 change: 1 addition & 0 deletions docs/dev/debt/libkernel.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [sceKernelGetSystemSwVersion](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) reports baseline system software version `0x01000000` ("01.000.000") for ProsperoStore (PPSA99000). The 0x28-byte layout (`uint64_t size` at 0, `versionString` at 8 and `version` at 0x24) matches [ProsperoStore's caller](https://github.com/blackbearreloaded/ProsperoStore/blob/20584011/src/diag/trace.cpp#L20-L26), [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/811bfcd7d1/src/core/libraries/kernel/kernel.h#L45-L49), [fpPS4](https://github.com/red-prig/fpPS4/blob/04cefd43e6/kernel/ps4_libkernel.pas#L502-L506) and [OpenOrbis](https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/blob/0a1aaf9dd4/include/orbis/_types/kernel.h#L256-L260). These sources support the structure layout, but not the reported version value: the console firmware version remains unverified. The checks are unverified too: a null pointer returns `SCE_KERNEL_ERROR_EFAULT` and a `size` other than 0x28 returns `SCE_KERNEL_ERROR_EINVAL`, while shadPS4 returns success for null and never reads `size`.
- [kern.rng_pseudo](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) - `sysctlbyname` fills the whole output buffer with bytes from the host's `std::random_device` and leaves the length unchanged; a write returns -1 with `EPERM` and a call without an output buffer throws. The only caller seen is mbedTLS's `mbedtls_hardware_poll` in the catalog's ProsperoLight boilerplate, which asks for 64-byte blocks and fails if fewer come back. The console's generator, its per-call maximum and its answer to a size query are unknown
- [kern.sdk_version](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) - `sysctlbyname` reports the system software version as the 4-byte value `0x01000000` (1.00), the value `sceKernelGetSystemSwVersion` reports; a write returns -1 with `EPERM`. The major version is byte 3 and the minor version byte 2, in hex digits that read as decimal (13.60 is `0x1360xxxx`), as [Capy Mobile](https://github.com/khalifa007/CapyMobile/blob/2758c016/src/ps5/platform.c#L64-L71) (PPSA92280), [remote_lua_loader](https://github.com/n0llptr/remote_lua_loader/blob/7c2840e475/savedata/misc.lua#L195-L209) and the [lapse payload](https://github.com/NetflixNHack/Netflix-N-Hack/blob/605eb93ba5/PS4/payloads/lapse.js#L436-L450) read it. Capy Mobile only displays it. The console's firmware version is not modeled and the low two bytes are unknown
- [machdep.tsc_freq](../../../core/libs/prx/libkernel/System/src/SystemConfiguration.cpp) (libkernel) - `sysctlbyname` reports the host TSC frequency as the 8-byte value `sceKernelGetTscFrequency` measures, since guest `rdtsc` reads the host counter, with FreeBSD's 64-bit [`sysctl_machdep_tsc_freq`](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/sys/x86/x86/tsc.c#L717-L736) layout and `ENOMEM` for a short buffer. The console's value is not known. A write, which FreeBSD takes as a new frequency, throws. PS5SX2 (PPSA99203) reads it at start-up and measures the TSC itself when the call fails
- [sceKernelGetProsperoSystemSwVersion](../../../core/libs/prx/libkernel/System/src/SoftwareVersion.cpp) (libkernel) reports system software version `0x01000000` ("01.000.000"); the console's firmware version is not modeled. The 0x28-byte block (a 64-bit size at 0, the version string at 8 and the packed version at 0x24) follows [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/Kernel/KernelSystem.cs), which Prospero Multi Tools (PPSA99110) and Prospero Explorer (PPSA99109) are built with and which sets the size to 40, and the same fields in [etaHEN](https://github.com/etaHEN/etaHEN/blob/main/Source%20Code/daemon/include/ipc.hpp) and [shsrv](https://github.com/ps5-payload-dev/shsrv/blob/master/sh.c). A size other than 0x28 returns `SCE_KERNEL_ERROR_EINVAL` without writing; whether the console checks the size is unverified, since etaHEN and shsrv declare a 0x30-byte block and do not set it
- [sceKernelGetAllowedSdkVersionOnSystem](../../../core/libs/prx/libkernel/System/src/SoftwareVersion.cpp) (libkernel) reports the system software version with the 12 patch bits set, `0x01000fff`, as [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/98fd0689/src/core/libraries/kernel/kernel.cpp) does on the PS4 and as [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/Kernel/KernelSystem.cs) describes it, which Prospero Explorer (PPSA99109) reads it through; a null pointer returns `SCE_KERNEL_ERROR_EINVAL`. The console's value and its errors are unverified
- [getuid, geteuid, getgid, getegid and issetugid](../../../core/libs/prx/libkernel/System/src/Process.cpp) (libkernel) report the root identity (0) and a process that never changed credentials (`issetugid` 0), as a jailbroken process has; the host user and group are not exposed to the guest. The values a title sees on a console are unverified
Expand Down
Loading