Merge pull request #5464 from milescoviello/fix/kernel-stat-null-buffer

fix(libkernel): fail sceKernelStat with EFAULT for a null buffer
This commit is contained in:
Dean 2026-10-14 14:24:24 +13:00 committed by GitHub
commit 979a4b9bb7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 4 additions and 3 deletions

View File

@ -294,15 +294,13 @@ int APS5_VABI sceKernelStat(const char* path, FileStat* sb) {
if (path == nullptr) {
throw std::invalid_argument(std::string(__func__) + ": path is null");
}
if (sb == nullptr) {
throw std::invalid_argument(std::string(__func__) + ": sb is null");
}
if (*path == '\0') return SceErrorFromErrno(2);
std::filesystem::path native;
if (const int error = ResolvePathError_nid_no_patch(path, native)) return SceKernelError(error);
native = File::PathOrRelinkedModule(native);
std::error_code error;
constexpr int GuestEnotdir = 20;
constexpr int GuestEfault = 14;
const auto status = std::filesystem::status(native, error);
if (error == std::errc::not_a_directory) return SceErrorFromErrno(GuestEnotdir);
if (!std::filesystem::exists(status)) {
@ -310,6 +308,7 @@ int APS5_VABI sceKernelStat(const char* path, FileStat* sb) {
}
const std::string_view guestPath(path);
if (!guestPath.empty() && guestPath.back() == '/' && !std::filesystem::is_directory(status)) return SceErrorFromErrno(GuestEnotdir);
if (sb == nullptr) return SceErrorFromErrno(GuestEfault);
File::FillFileStat(native, sb);
return 0;
}

View File

@ -220,6 +220,8 @@ int main() {
Require(chmod_nid_postfix("", 0600) == -1 && *__error_nid_postfix() == 2);
Require(chmod_nid_postfix("anyps5_missing_chmod_path", 0600) == -1 && *__error_nid_postfix() == 2);
Require(sceKernelChmod_nid_postfix("anyps5_missing_chmod_path", 0600) == static_cast<int>(0x80020002u));
Require(sceKernelStat("anyps5_missing_chmod_path", nullptr) == static_cast<int>(0x80020002u));
Require(sceKernelStat(".", nullptr) == static_cast<int>(0x8002000eu));
Require(sceKernelDebugOutText(-1, "text") == static_cast<int>(0x80020016u));
std::uint64_t throttling[4] = {1, 2, 3, 4};
Require(sceKernelWriteThrottlingStatus(throttling) == 0);