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.
This commit is contained in:
Hussein Kadhim 2026-10-13 19:44:27 +03:00 committed by MarcZX100
parent 8cf6a0bc3a
commit 2096410b29
2 changed files with 10 additions and 6 deletions

View File

@ -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};

View File

@ -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"));