[PATCH v2 2/3] ntdll: Implement __fastfail().
Jinoh Kang
jinoh.kang.kr at gmail.com
Mon Dec 6 07:56:45 CST 2021
__fastfail() is used by the Visual C++ runtime and Windows system
libraries to signal that the in-process state is corrupted and
unrecoverable.
If __fastfail() is invoked, the NT kernel raises a second-chance
non-continuable exception STATUS_STACK_BUFFER_OVERRUN. This quickly
terminates the process, bypassing all in-process exception handlers
(since they all rely on the potentially corrupted process state).
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
dlls/ntdll/unix/signal_arm.c | 14 ++++++++++++--
dlls/ntdll/unix/signal_arm64.c | 11 +++++++++++
dlls/ntdll/unix/signal_i386.c | 7 +++++++
dlls/ntdll/unix/signal_x86_64.c | 7 +++++++
4 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index dbc2770f72e..1816e210644 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -809,13 +809,23 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
switch (get_trap_code(signal, context))
{
case TRAP_ARM_PRIVINFLT: /* Invalid opcode exception */
- if (*(WORD *)PC_sig(context) == 0xdefe) /* breakpoint */
+ switch (*(WORD *)PC_sig(context))
{
+ case 0xdefb: /* __fastfail */
+ rec.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+ rec.ExceptionFlags = EH_NONCONTINUABLE;
+ rec.NumberParameters = 1;
+ rec.ExceptionInformation[0] = REGn_sig(0, context);
+ setup_exception( context, &rec, FALSE );
+ return;
+ case 0xdefe: /* breakpoint */
rec.ExceptionCode = EXCEPTION_BREAKPOINT;
rec.NumberParameters = 1;
break;
+ default:
+ rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+ break;
}
- rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break;
case TRAP_ARM_PAGEFLT: /* Page fault */
rec.NumberParameters = 2;
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index ef70d4df44b..fe80732c03d 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -905,6 +905,17 @@ static void bus_handler( int signal, siginfo_t *siginfo, void *sigcontext )
static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
EXCEPTION_RECORD rec = { 0 };
+ ucontext_t *context = sigcontext;
+
+ if ((get_fault_esr( context ) & 0xfe00ffffU) == 0xf200f003U)
+ {
+ rec.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+ rec.ExceptionFlags = EH_NONCONTINUABLE;
+ rec.NumberParameters = 1;
+ rec.ExceptionInformation[0] = REGn_sig( 0, context );
+ setup_exception( sigcontext, &rec, FALSE );
+ return;
+ }
switch (siginfo->si_code)
{
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index e18aed2c222..6d448b99223 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -1660,6 +1660,13 @@ static BOOL handle_interrupt( unsigned int interrupt, ucontext_t *sigcontext, vo
switch(interrupt)
{
+ case 0x29:
+ rec->ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+ rec->ExceptionFlags = EH_NONCONTINUABLE;
+ rec->NumberParameters = 1;
+ rec->ExceptionInformation[0] = context->Ecx;
+ setup_raise_exception( sigcontext, stack, rec, xcontext, FALSE );
+ return TRUE;
case 0x2d:
if (!is_wow64)
{
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index ff4a40c7933..39bf1bcc835 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2441,6 +2441,13 @@ static inline BOOL handle_interrupt( ucontext_t *sigcontext, EXCEPTION_RECORD *r
switch (ERROR_sig(sigcontext) >> 3)
{
+ case 0x29:
+ rec->ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+ rec->ExceptionFlags = EH_NONCONTINUABLE;
+ rec->NumberParameters = 1;
+ rec->ExceptionInformation[0] = context->Rcx;
+ setup_raise_exception( sigcontext, rec, xcontext, FALSE );
+ return TRUE;
case 0x2c:
rec->ExceptionCode = STATUS_ASSERTION_FAILURE;
break;
--
2.31.1
More information about the wine-devel
mailing list