From 5f10545b199ce44de7f91d719131767396e320c7 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 17 Sep 2019 16:02:55 +0200 Subject: [PATCH] ntdll: Don't use virtual_uninterrupted_read_memory() for invalid %gs check. It doesn't work for code in system libraries. This is a partial revert of 58139dcb125390b9a2bcd79869d571337d8ab3d8. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47769 Signed-off-by: Alexandre Julliard --- dlls/ntdll/signal_i386.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 8d1c591504d..f15b3276244 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -1595,17 +1595,16 @@ static inline DWORD is_privileged_instr( CONTEXT *context ) */ static inline BOOL check_invalid_gs( ucontext_t *sigcontext, CONTEXT *context ) { - BYTE instr[14]; - unsigned int i, len; + unsigned int prefix_count = 0; + const BYTE *instr = (BYTE *)context->Eip; WORD system_gs = x86_thread_data()->gs; if (context->SegGs == system_gs) return FALSE; if (!wine_ldt_is_system( context->SegCs )) return FALSE; /* only handle faults in system libraries */ - if (virtual_is_valid_code_address( (BYTE *)context->Eip, 1 )) return FALSE; + if (virtual_is_valid_code_address( instr, 1 )) return FALSE; - len = virtual_uninterrupted_read_memory( (BYTE *)context->Eip, instr, sizeof(instr) ); - for (i = 0; i < len; i++) switch (instr[i]) + for (;;) switch(*instr) { /* instruction prefixes */ case 0x2e: /* %cs: */ @@ -1618,6 +1617,8 @@ static inline BOOL check_invalid_gs( ucontext_t *sigcontext, CONTEXT *context ) case 0xf0: /* lock */ case 0xf2: /* repne */ case 0xf3: /* repe */ + if (++prefix_count >= 15) return FALSE; + instr++; continue; case 0x65: /* %gs: */ TRACE( "%04x/%04x at %p, fixing up\n", context->SegGs, system_gs, instr ); @@ -1628,7 +1629,6 @@ static inline BOOL check_invalid_gs( ucontext_t *sigcontext, CONTEXT *context ) default: return FALSE; } - return FALSE; }