Last active
April 28, 2020 17:39
-
-
Save awesie/13bb500acc565214b2bf2b639145a92e to your computer and use it in GitHub Desktop.
Includes patches for 47198 and 45667.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c | |
index 67a785e..8e00d62 100644 | |
--- a/dlls/ntdll/signal_i386.c | |
+++ b/dlls/ntdll/signal_i386.c | |
@@ -437,6 +437,8 @@ static wine_signal_handler handlers[256]; | |
extern void DECLSPEC_NORETURN __wine_syscall_dispatcher( void ); | |
extern NTSTATUS WINAPI __syscall_NtGetContextThread( HANDLE handle, CONTEXT *context ); | |
+static int wine_cs; | |
+ | |
/* convert from straight ASCII to Unicode without depending on the current codepage */ | |
static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len ) | |
{ | |
@@ -885,7 +887,7 @@ static inline void * SIGNALFUNC init_handler( const ucontext_t *sigcontext, WORD | |
} | |
#endif | |
- if (!wine_ldt_is_system(CS_sig(sigcontext)) || | |
+ if ((CS_sig(sigcontext) != wine_cs && !wine_ldt_is_system(CS_sig(sigcontext))) || | |
!wine_ldt_is_system(SS_sig(sigcontext))) /* 16-bit mode */ | |
{ | |
/* | |
@@ -1576,7 +1578,7 @@ static inline DWORD is_privileged_instr( CONTEXT *context ) | |
const BYTE *instr; | |
unsigned int prefix_count = 0; | |
- if (!wine_ldt_is_system( context->SegCs )) return 0; | |
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0; | |
instr = (BYTE *)context->Eip; | |
for (;;) switch(*instr) | |
@@ -1674,7 +1676,7 @@ static inline BOOL check_invalid_gs( CONTEXT *context ) | |
WORD system_gs = x86_thread_data()->gs; | |
if (context->SegGs == system_gs) return FALSE; | |
- if (!wine_ldt_is_system( context->SegCs )) return FALSE; | |
+ if (context->SegCs != wine_cs && !wine_ldt_is_system( context->SegCs )) return 0; | |
/* only handle faults in system libraries */ | |
if (virtual_is_valid_code_address( instr, 1 )) return FALSE; | |
@@ -1916,7 +1918,7 @@ static EXCEPTION_RECORD *setup_exception_record( ucontext_t *sigcontext, void *s | |
EIP_sig(sigcontext) = (DWORD)func; | |
/* clear single-step, direction, and align check flag */ | |
EFL_sig(sigcontext) &= ~(0x100|0x400|0x40000); | |
- CS_sig(sigcontext) = wine_get_cs(); | |
+ CS_sig(sigcontext) = wine_cs; | |
DS_sig(sigcontext) = wine_get_ds(); | |
ES_sig(sigcontext) = wine_get_es(); | |
FS_sig(sigcontext) = wine_get_fs(); | |
@@ -2394,6 +2396,32 @@ static void ldt_unlock(void) | |
else RtlLeaveCriticalSection( &ldt_section ); | |
} | |
+#include <sys/mman.h> | |
+void signal_init_cs(void) | |
+{ | |
+ static const BYTE int80_ret[] = { 0xcd, 0x80, 0xc3 }; | |
+ void *sysinfo; | |
+ LDT_ENTRY entry; | |
+ | |
+ if (!wine_cs) | |
+ { | |
+ wine_cs = wine_ldt_alloc_entries( 1 ); | |
+ | |
+ /* Overwrite VDSO to use int $0x80 instead of sysenter. */ | |
+ asm ("mov %%gs:0x10, %0" : "=r" (sysinfo)); | |
+ mprotect( (void *)((INT_PTR)sysinfo & ~0xfff), 0x1000, PROT_READ | PROT_EXEC | PROT_WRITE ); | |
+ memcpy( sysinfo, int80_ret, sizeof(int80_ret)); | |
+ mprotect( (void *)((INT_PTR)sysinfo & ~0xfff), 0x1000, PROT_READ | PROT_EXEC ); | |
+ } | |
+ | |
+ wine_ldt_set_base( &entry, 0 ); | |
+ wine_ldt_set_limit( &entry, (UINT_PTR)-1 ); | |
+ wine_ldt_set_flags( &entry, WINE_LDT_FLAGS_CODE|WINE_LDT_FLAGS_32BIT ); | |
+ wine_ldt_set_entry( wine_cs, &entry ); | |
+ | |
+ wine_set_cs( wine_cs ); | |
+} | |
+ | |
/********************************************************************** | |
* signal_alloc_thread | |
@@ -2433,6 +2461,7 @@ NTSTATUS signal_alloc_thread( TEB **teb ) | |
status = STATUS_TOO_MANY_THREADS; | |
} | |
} | |
+ | |
return status; | |
} | |
@@ -2479,6 +2508,8 @@ void signal_init_thread( TEB *teb ) | |
wine_ldt_init_fs( thread_data->fs, &fs_entry ); | |
thread_data->gs = wine_get_gs(); | |
+ signal_init_cs(); | |
+ | |
#ifdef __GNUC__ | |
__asm__ volatile ("fninit; fldcw %0" : : "m" (fpu_cw)); | |
#else | |
diff --git a/include/wine/library.h b/include/wine/library.h | |
index 7395a11..56e7490 100644 | |
--- a/include/wine/library.h | |
+++ b/include/wine/library.h | |
@@ -192,6 +192,7 @@ __DEFINE_SET_SEG(fs) | |
__DEFINE_SET_SEG(gs) | |
#undef __DEFINE_GET_SEG | |
#undef __DEFINE_SET_SEG | |
+extern void wine_set_cs(unsigned int); | |
#endif /* __i386__ */ | |
diff --git a/libs/wine/ldt.c b/libs/wine/ldt.c | |
index 3e7369f..66dec6c 100644 | |
--- a/libs/wine/ldt.c | |
+++ b/libs/wine/ldt.c | |
@@ -460,6 +460,10 @@ __ASM_GLOBAL_FUNC( wine_get_es, "movw %es,%ax\n\tret" ) | |
__ASM_GLOBAL_FUNC( wine_get_fs, "movw %fs,%ax\n\tret" ) | |
__ASM_GLOBAL_FUNC( wine_get_gs, "movw %gs,%ax\n\tret" ) | |
__ASM_GLOBAL_FUNC( wine_get_ss, "movw %ss,%ax\n\tret" ) | |
+__ASM_GLOBAL_FUNC( wine_set_cs, "movl 4(%esp),%eax\n\t" | |
+ "xchg 0(%esp),%eax\n\t" | |
+ "push %eax\n\t" | |
+ "retf" ) | |
__ASM_GLOBAL_FUNC( wine_set_fs, "movl 4(%esp),%eax\n\tmovw %ax,%fs\n\tret" ) | |
__ASM_GLOBAL_FUNC( wine_set_gs, "movl 4(%esp),%eax\n\tmovw %ax,%gs\n\tret" ) | |
diff --git a/libs/wine/wine.map b/libs/wine/wine.map | |
index 72ffed8..c41f567 100644 | |
--- a/libs/wine/wine.map | |
+++ b/libs/wine/wine.map | |
@@ -114,6 +114,7 @@ WINE_1.0 | |
wine_mmap_remove_reserved_area; | |
wine_pthread_get_functions; | |
wine_pthread_set_functions; | |
+ wine_set_cs; | |
wine_set_fs; | |
wine_set_gs; | |
wine_switch_to_stack; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment