From 091438f99ba64306cfa4f12248ecac624d4db1ba Mon Sep 17 00:00:00 2001 From: Hussein Kadhim Date: Tue, 13 Oct 2026 20:04:44 +0300 Subject: [PATCH] fix(libkernel): fail sysctl with ENOTDIR when a leaf MIB has a trailing component FreeBSD sysctl_find_oid returns ENOTDIR when the MIB continues below a leaf object. The supported hw.ncpu, hw.model, hw.physmem and kern.arandom MIBs threw an unsupported MIB error instead. (cherry picked from commit 6968aea8af578c4d56dc614cbe449274bb6e76e7) --- .../libkernel/System/src/SystemConfiguration.cpp | 8 ++++++++ core/libs/tests/GuestSystemConfiguration.cpp | 13 +++++++++++++ 2 files changed, 21 insertions(+) diff --git a/core/libs/prx/libkernel/System/src/SystemConfiguration.cpp b/core/libs/prx/libkernel/System/src/SystemConfiguration.cpp index 672c9d291..b55817834 100644 --- a/core/libs/prx/libkernel/System/src/SystemConfiguration.cpp +++ b/core/libs/prx/libkernel/System/src/SystemConfiguration.cpp @@ -44,6 +44,10 @@ int CopyOut(const void* value, std::size_t size, void* oldValue, std::size_t* ol return 0; } +bool IsLeafMib(const int* name) { + return (name[0] == 6 && (name[1] == 2 || name[1] == 3 || name[1] == 5)) || (name[0] == 1 && name[1] == 37); +} + std::string HostCpuModel() { #if defined(__x86_64__) || defined(__i386__) if (__get_cpuid_max(0x80000000, nullptr) < 0x80000004) return {}; @@ -169,6 +173,10 @@ int APS5_VABI sysctl_nid_postfix(const int* name, std::uint32_t nameLength, void *oldLength = count; return 0; } + if (nameLength > 2 && IsLeafMib(name)) { + *__error_nid_postfix() = 20; + return -1; + } std::string mib; for (std::uint32_t i = 0; i < nameLength; ++i) mib += (i == 0 ? "" : ".") + std::to_string(name[i]); throw std::runtime_error(std::string(__func__) + ": unsupported MIB " + mib); diff --git a/core/libs/tests/GuestSystemConfiguration.cpp b/core/libs/tests/GuestSystemConfiguration.cpp index 1ad0f5c6f..c599a5ac2 100644 --- a/core/libs/tests/GuestSystemConfiguration.cpp +++ b/core/libs/tests/GuestSystemConfiguration.cpp @@ -156,6 +156,18 @@ static void CheckPathnameSysctl() { length = sizeof(buffer); Require(sysctl_nid_postfix(mibSelf, 4, buffer, &length, buffer, sizeof(buffer)) == -1 && *__error_nid_postfix() == 1); } +static void CheckLeafWithTrailingComponent() { + const int leaves[][2] = {{6, 3}, {6, 2}, {6, 5}, {1, 37}}; + for (const auto& leaf : leaves) { + const int mib[] = {leaf[0], leaf[1], 0}; + char buffer[8] = {}; + std::size_t length = sizeof(buffer); + *__error_nid_postfix() = 13; + Require(sysctl_nid_postfix(mib, 3, buffer, &length, nullptr, 0) == -1 && *__error_nid_postfix() == 20); + Require(sysctl_nid_postfix(mib, 3, buffer, &length, buffer, sizeof(buffer)) == -1 && *__error_nid_postfix() == 20); + Require(length == sizeof(buffer)); + } +} static void CheckSystemSwVersion() { *__error_nid_postfix() = 13; Require(sceKernelGetSystemSwVersion_nid_postfix(nullptr) == SCE_KERNEL_ERROR_EFAULT && *__error_nid_postfix() == 13); @@ -257,6 +269,7 @@ int main() { #endif CheckMachdepCachelineSizeSysctl(); CheckPathnameSysctl(); + CheckLeafWithTrailingComponent(); CheckSystemSwVersion(); CheckPseudoRandomSysctl(); CheckSdkVersionSysctl();