From 2096410b2959132a1d495808a763dc8e1916da13 Mon Sep 17 00:00:00 2001 From: Hussein Kadhim Date: Tue, 13 Oct 2026 19:44:27 +0300 Subject: [PATCH] fix(libkernel): report EPERM before EINVAL when writing kern.proc.pathname FreeBSD sysctl_root rejects a write to a read-only node with EPERM before the node handler checks the MIB length, so a write with a short or long kern.proc.pathname MIB fails with EPERM. sysctlbyname for kern.proc.pathname now goes through sysctl with its 3-component MIB so it follows the same order. --- .../prx/libkernel/System/src/SystemConfiguration.cpp | 12 ++++++------ core/libs/tests/GuestSystemConfiguration.cpp | 4 ++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/core/libs/prx/libkernel/System/src/SystemConfiguration.cpp b/core/libs/prx/libkernel/System/src/SystemConfiguration.cpp index 672c9d291..795a4d019 100644 --- a/core/libs/prx/libkernel/System/src/SystemConfiguration.cpp +++ b/core/libs/prx/libkernel/System/src/SystemConfiguration.cpp @@ -138,14 +138,14 @@ int APS5_VABI sysctl_nid_postfix(const int* name, std::uint32_t nameLength, void return CopyOut(&physmem, sizeof(physmem), oldValue, oldLength); } if (nameLength >= 3 && name[0] == 1 && name[1] == 14 && name[2] == 12) { - if (nameLength != 4) { - *__error_nid_postfix() = 22; - return -1; - } if (newValue != nullptr) { *__error_nid_postfix() = 1; return -1; } + if (nameLength != 4) { + *__error_nid_postfix() = 22; + return -1; + } const int pid = name[3]; if (pid != -1 && pid != getpid_nid_postfix()) { *__error_nid_postfix() = 3; @@ -184,8 +184,8 @@ int APS5_VABI sysctlbyname_nid_postfix(const char* name, void* oldValue, std::si return -1; } if (std::strcmp(name, "kern.proc.pathname") == 0) { - *__error_nid_postfix() = 22; - return -1; + static constexpr int mib[] = {1, 14, 12}; + return sysctl_nid_postfix(mib, 3, oldValue, oldLength, newValue, newLength); } if (std::strcmp(name, "kern.arandom") == 0) { static constexpr int mib[] = {1, 37}; diff --git a/core/libs/tests/GuestSystemConfiguration.cpp b/core/libs/tests/GuestSystemConfiguration.cpp index 1ad0f5c6f..b960fb85f 100644 --- a/core/libs/tests/GuestSystemConfiguration.cpp +++ b/core/libs/tests/GuestSystemConfiguration.cpp @@ -127,6 +127,10 @@ static void CheckPathnameSysctl() { const int mibTooLong[] = {1, 14, 12, -1, 0}; Require(sysctl_nid_postfix(mibTooLong, 5, buffer, &length, nullptr, 0) == -1 && *__error_nid_postfix() == 22); + Require(sysctl_nid_postfix(mibTooShort, 3, buffer, &length, buffer, sizeof(buffer)) == -1 && *__error_nid_postfix() == 1); + Require(sysctl_nid_postfix(mibTooLong, 5, buffer, &length, buffer, sizeof(buffer)) == -1 && *__error_nid_postfix() == 1); + Require(sysctlbyname_nid_postfix("kern.proc.pathname", buffer, &length, buffer, sizeof(buffer)) == -1 && *__error_nid_postfix() == 1); + const int mibSelf[] = {1, 14, 12, -1}; length = 0; Require(sysctl_nid_postfix(mibSelf, 4, nullptr, &length, nullptr, 0) == 0 && length == sizeof("/app0/eboot.bin"));