Merge pull request #14979 from fogydes/fix/libSceFiber-pointer-validation

fix(libSceFiber): return INVALID from sceFiberOptParamInitialize for an unwritable pointer
This commit is contained in:
Dean authored and GitHub committed 2026-11-06 12:58:45 +13:00
commit 495b960d4b
3 files changed
+25 -1

No files matched your search

+7 -1
View File
@@ -624,7 +624,13 @@ int32_t APS5_VABI sceFiberRename(FiberObject* object, const char* name) {
int32_t APS5_VABI sceFiberOptParamInitialize(FiberOptParam* opt_param) {
if (!opt_param) return SCE_FIBER_ERROR_NULL;
std::memset(opt_param, 0, FIBER_OPT_PARAM_SIZE);
const std::uint8_t zero[FIBER_OPT_PARAM_SIZE] = {};
const auto preserved = errno;
if (!GuestCopyOut_nid_no_patch(opt_param, zero, sizeof(zero))) {
errno = preserved;
return SCE_FIBER_ERROR_INVALID;
}
errno = preserved;
return SCE_OK;
}
+17
View File
@@ -566,6 +566,23 @@ int main(int argc, char** argv) {
#endif
FiberObject* self = nullptr;
Require(sceFiberGetSelf(&self) == FiberErrorPermission, "no fiber on the thread");
Require(sceFiberOptParamInitialize(nullptr) == FiberErrorNull, "null opt param");
Require(sceFiberOptParamInitialize(reinterpret_cast<FiberOptParam*>(0x10)) == FiberErrorInvalid, "unwritable opt param");
struct alignas(8) AlignedOptParamBuffer {
std::uint8_t bytes[0x80];
std::uint32_t sentinel = 0x5a5a5a5a;
} storage;
std::memset(storage.bytes, 0xA5, sizeof(storage.bytes));
Require(sceFiberOptParamInitialize(reinterpret_cast<FiberOptParam*>(storage.bytes)) == 0, "initialize opt param");
bool allZero = true;
for (std::size_t i = 0; i < sizeof(storage.bytes); ++i) {
if (storage.bytes[i] != 0) {
allZero = false;
break;
}
}
Require(allZero, "opt param cleared");
Require(storage.sentinel == 0x5a5a5a5a, "sentinel intact");
Require(_sceFiberInitializeImpl_nid_postfix(g_first, "first", FirstEntry, 11, g_firstContext.data(), g_firstContext.size(), nullptr, 0) == 0, "initialize first");
Require(_sceFiberInitializeImpl_nid_postfix(g_second, "second", SecondEntry, 22, g_secondContext.data(), g_secondContext.size(), nullptr, 0) == 0, "initialize second");
const auto threadCsr = _mm_getcsr();
+1
View File
@@ -2,6 +2,7 @@
### Functional
- [sceFiberOptParamInitialize](../../../core/libs/prx/libSceFiber/Export.cpp) returns SCE_FIBER_ERROR_INVALID when the destination pointer is unwritable. This is a defensive host-protection fallback; whether the console raises a signal or faults on unmapped or read-only memory is not measured.
- [sceFiberGetInfo](../../../core/libs/prx/libSceFiber/Export.cpp) reports the requested-size window at the top of the host stack used for execution, rather than the original caller buffer, which is retained and pinned. The additional 1 MiB host-call margin below that window is not included in `size_context`. Planet Coaster (PPSA01736 v01.017) uses this range for ChakraCore garbage-collector stack scans; reporting the unused caller buffer makes the scan cross unmapped memory. The range is covered by a regression test while running, switching and migrating a fiber between threads. Console behavior for substituted host stacks has no direct equivalent and is not measured.
### Unknown function info