Skip to content

Commit

Permalink
Telemetry: Adds tracker for non-canonical memory access crash
Browse files Browse the repository at this point in the history
This may be useful for tracking TSO faulting when it manages to fetch
stale data. While most TSO crashes are due to nullptr dereferences, this
can still check for the corruption case.
  • Loading branch information
Sonicadvance1 committed Mar 22, 2024
1 parent 8852d94 commit 5a35e11
Show file tree
Hide file tree
Showing 6 changed files with 12 additions and 3 deletions.
1 change: 1 addition & 0 deletions FEXCore/Source/Utils/Telemetry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ namespace FEXCore::Telemetry {
"Uses 32-bit Segment SS",
"Uses 32-bit Segment CS",
"Uses 32-bit Segment DS",
"Non-Canonical 64-bit address access",
};

static bool Enabled {true};
Expand Down
1 change: 1 addition & 0 deletions FEXCore/include/FEXCore/Utils/Telemetry.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace FEXCore::Telemetry {
TYPE_USES_32BIT_SEGMENT_SS,
TYPE_USES_32BIT_SEGMENT_CS,
TYPE_USES_32BIT_SEGMENT_DS,
TYPE_UNHANDLED_NONCANONICAL_ADDRESS,
TYPE_LAST,
};

Expand Down
5 changes: 5 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,11 @@ namespace FEX::HLE {
// FEX is hard crashing at this point and won't hit regular shutdown routines.
// Add the signal to the crash mask.
CrashMask |= (1ULL << Signal);
if (Signal == SIGSEGV &&
reinterpret_cast<uint64_t>(SigInfo.si_addr) >= SyscallHandler::TASK_MAX_64BIT) {
// Tried accessing invalid non-canonical x86-64 address.
UnhandledNonCanonical = true;
}
SaveTelemetry();
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ namespace FEX::HLE {
FEX_CONFIG_OPT(Core, CORE);
fextl::string const ApplicationName;
FEXCORE_TELEMETRY_INIT(CrashMask, TYPE_CRASH_MASK);
FEXCORE_TELEMETRY_INIT(UnhandledNonCanonical, TYPE_UNHANDLED_NONCANONICAL_ADDRESS);

enum DefaultBehaviour {
DEFAULT_TERM,
Expand Down
2 changes: 2 additions & 0 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,8 @@ class SyscallHandler : public FEXCore::HLE::SyscallHandler, FEXCore::HLE::Source
bool NeedXIDCheck() const { return NeedToCheckXID; }
void DisableXIDCheck() { NeedToCheckXID = false; }

constexpr static uint64_t TASK_MAX_64BIT = (1ULL << 48);

protected:
SyscallHandler(FEXCore::Context::Context *_CTX, FEX::HLE::SignalDelegator *_SignalDelegation);

Expand Down
5 changes: 2 additions & 3 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,19 +449,18 @@ namespace FEX::HLE {

REGISTER_SYSCALL_IMPL_FLAGS(arch_prctl, SyscallFlags::DEFAULT,
[](FEXCore::Core::CpuStateFrame *Frame, int code, unsigned long addr) -> uint64_t {
constexpr uint64_t TASK_MAX = (1ULL << 48); // 48-bits until we can query the host side VA sanely. AArch64 doesn't expose this in cpuinfo
uint64_t Result{};
switch (code) {
case 0x1001: // ARCH_SET_GS
if (addr >= TASK_MAX) {
if (addr >= SyscallHandler::TASK_MAX_64BIT) {
// Ignore a non-canonical address
return -EPERM;
}
Frame->State.gs_cached = addr;
Result = 0;
break;
case 0x1002: // ARCH_SET_FS
if (addr >= TASK_MAX) {
if (addr >= SyscallHandler::TASK_MAX_64BIT) {
// Ignore a non-canonical address
return -EPERM;
}
Expand Down

0 comments on commit 5a35e11

Please sign in to comment.