fix(libc): validate fesetenv against the host MXCSR mask

This commit is contained in:
Kraken committed 2026-10-21 08:02:57 +01:00
1 parent 05d3768006
commit 40add4dc2f
3 files changed
+13 -4

No files matched your search

+5 -1
View File
@@ -1,4 +1,5 @@
#include <mutex>
#include <array>
#include <bit>
#include <cstddef>
#include <cstdint>
@@ -792,7 +793,10 @@ SonyDconst _LSnan_nid_postfix {{1, 0, 0, 0x8000, 0x7fff, 0, 0, 0}};
int APS5_VABI fesetenv_nid_postfix(const GuestFloatingPointEnvironment* environment) {
if (environment == nullptr) throw std::invalid_argument("fesetenv: null environment");
if ((environment->mxcsr & 0xffff0000u) != 0) throw std::invalid_argument("fesetenv: unsupported MXCSR bits");
alignas(16) std::array<std::uint32_t, 128> state;
asm volatile("fxsave %0" : "=m"(state));
const auto supported = state[7] != 0 ? state[7] : 0xffbfu;
if ((environment->mxcsr & ~supported) != 0) throw std::invalid_argument("fesetenv: unsupported MXCSR bits");
asm volatile("fldenv %0" : : "m"(*environment) : "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)");
_mm_setcsr(environment->mxcsr);
return 0;
+7 -2
View File
@@ -146,13 +146,18 @@ void BoundsAndErrors() {
*__error_nid_postfix()=123;
try { setEnvironment(nullptr); } catch(const std::invalid_argument&) { rejected=true; }
Require(rejected && Same(Read(),original) && *__error_nid_postfix()==123,"null rejected without state or errno change");
for(unsigned reserved:{0x10000u,0x80000000u,0xffff0000u}) {
alignas(16) std::array<std::uint32_t,128> extended;
asm volatile("fxsave %0" : "=m"(extended));
const auto supported=extended[7] ? extended[7] : 0xffbfu;
for(unsigned bit=0;bit<32;++bit) {
const auto reserved=1u<<bit;
if((supported&reserved)!=0) continue;
auto desired=original;
desired.x87[0]^=0xc00;
desired.mxcsr|=reserved;
rejected=false;
try { setEnvironment(&desired); } catch(const std::invalid_argument&) { rejected=true; }
Require(rejected && Same(Read(),original) && *__error_nid_postfix()==123,"unsupported MXCSR rejected before x87 changes");
Require(rejected && Same(Read(),original) && *__error_nid_postfix()==123,"host-unsupported MXCSR rejected before x87 changes");
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
### Unknown function info
- [fesetenv](../../../core/libs/prx/libc/src/Math.cpp) (libSceLibcInternal, implemented in libc, NID `Q-bLp+b-RVY`) uses the 32-byte amd64 environment and x87/MXCSR restore sequence in the [public SDK fenv.h](https://github.com/ps5-payload-dev/sdk/blob/a7685ce8e97ce1f8a4f38253a41d54241c9124f1/include/freebsd/fenv.h). The console layout, behavior and module/library versions are unmeasured. Null pointers and reserved MXCSR bits throw before changing state; console fault behavior for invalid environments is unverified. The separate `__fe_dfl_env` object remains missing and its console initializer is unknown.
- [fesetenv](../../../core/libs/prx/libc/src/Math.cpp) (libSceLibcInternal, implemented in libc, NID `Q-bLp+b-RVY`) uses the 32-byte amd64 environment and x87/MXCSR restore sequence in the [public SDK fenv.h](https://github.com/ps5-payload-dev/sdk/blob/a7685ce8e97ce1f8a4f38253a41d54241c9124f1/include/freebsd/fenv.h). The console layout, behavior and module/library versions are unmeasured. Null pointers and MXCSR bits unsupported by the current host's `FXSAVE` mask throw before changing state; a zero mask uses the architectural `0xffbf` fallback. Console fault behavior for invalid environments is unverified. The separate `__fe_dfl_env` object remains missing and its console initializer is unknown.
- [strtonum](../../../core/libs/prx/libc/src/StringExtensions.cpp) (libc) is unverified on the console. Its signature, decimal parsing, inclusive bounds, error strings, error precedence and errno preservation follow [FreeBSD 11.4 strtonum.c](https://github.com/freebsd/freebsd-src/blob/8c639945a44588f6cfdddfb057bb5aad88735da0/lib/libc/stdlib/strtonum.c). Parsing uses the host `strtoll` with base 10.