[PATCH 2/2] ntdll: Filter EFlags from user-supplied CONTEXT on x86 and x64.
Jinoh Kang
wine at gitlab.winehq.org
Mon Jun 20 06:29:36 CDT 2022
From: Jinoh Kang <jinoh.kang.kr at gmail.com>
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
dlls/ntdll/tests/exception.c | 2 --
dlls/ntdll/unix/signal_i386.c | 2 +-
dlls/ntdll/unix/signal_x86_64.c | 4 ++--
dlls/ntdll/unix/thread.c | 20 +++++++++++++++++++-
dlls/ntdll/unix/unix_private.h | 13 +++++++++++++
5 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index ee486380b8d..169045bf5e6 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -10721,7 +10721,6 @@ static void test_eflags_sanitization(void)
ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status);
status = pNtGetContextThread(thread, &context);
ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status);
- todo_wine
ok(context.EFlags == max_eflags, "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags);
context.EFlags = 0;
@@ -10729,7 +10728,6 @@ static void test_eflags_sanitization(void)
ok(status == STATUS_SUCCESS, "NtSetContextThread failed with %lx\n", status);
status = pNtGetContextThread(thread, &context);
ok(status == STATUS_SUCCESS, "NtGetContextThread failed with %lx\n", status);
- todo_wine
ok(context.EFlags == min_eflags, "Expected EFlags to be %#lx, got %#lx\n", max_eflags, context.EFlags);
context.EFlags = old_eflags;
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 7be0c39c424..9be0769904d 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -941,7 +941,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
frame->esp = context->Esp;
frame->ebp = context->Ebp;
frame->eip = context->Eip;
- frame->eflags = context->EFlags;
+ frame->eflags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_I386 );
frame->cs = context->SegCs;
frame->ss = context->SegSs;
}
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 6c87e347eac..c4f67a16cc9 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -1788,7 +1788,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
frame->rsp = context->Rsp;
frame->rbp = context->Rbp;
frame->rip = context->Rip;
- frame->eflags = context->EFlags;
+ frame->eflags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_AMD64 );
frame->cs = context->SegCs;
frame->ss = context->SegSs;
}
@@ -2002,7 +2002,7 @@ NTSTATUS set_thread_wow64_context( HANDLE handle, const void *ctx, ULONG size )
wow_frame->Esp = context->Esp;
wow_frame->Ebp = context->Ebp;
wow_frame->Eip = context->Eip;
- wow_frame->EFlags = context->EFlags;
+ wow_frame->EFlags = arch_flags_reg_from_user( context->EFlags, IMAGE_FILE_MACHINE_I386 );
wow_frame->SegCs = cs32_sel;
wow_frame->SegSs = ds64_sel;
cpu->Flags |= WOW64_CPURESERVED_FLAG_RESET_STATE;
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index ad47a5fce74..e0d44bb4a38 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -1663,13 +1663,31 @@ NTSTATUS WINAPI NtQueueApcThread( HANDLE handle, PNTAPCFUNC func, ULONG_PTR arg1
NTSTATUS set_thread_context( HANDLE handle, const void *context, BOOL *self, USHORT machine )
{
context_t server_contexts[2];
- unsigned int count = 0;
+ unsigned int count = 0, i;
NTSTATUS ret;
context_to_server( &server_contexts[count++], native_machine, context, machine );
if (machine != native_machine)
context_to_server( &server_contexts[count++], machine, context, machine );
+ for (i = 0; i < count; i++)
+ {
+ unsigned int *flags_ptr;
+ if (!(server_contexts[i].flags & SERVER_CTX_CONTROL)) continue;
+ switch (server_contexts[i].machine)
+ {
+ case IMAGE_FILE_MACHINE_I386:
+ flags_ptr = &server_contexts[i].ctl.i386_regs.eflags;
+ break;
+ case IMAGE_FILE_MACHINE_AMD64:
+ flags_ptr = &server_contexts[i].ctl.x86_64_regs.flags;
+ break;
+ default:
+ continue;
+ }
+ *flags_ptr = arch_flags_reg_from_user( *flags_ptr, machine );
+ }
+
SERVER_START_REQ( set_thread_context )
{
req->handle = wine_server_obj_handle( handle );
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 795fc148479..3558f898b36 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -458,4 +458,17 @@ static inline NTSTATUS map_section( HANDLE mapping, void **ptr, SIZE_T *size, UL
0, NULL, size, ViewShare, 0, protect );
}
+static inline DWORD arch_flags_reg_from_user( DWORD flags, USHORT machine )
+{
+ switch (machine)
+ {
+ case IMAGE_FILE_MACHINE_I386:
+ return (flags & 0x003f0fd7) | 0x00000202;
+ case IMAGE_FILE_MACHINE_AMD64:
+ return (flags & 0x00210fd5) | 0x00000200;
+ default:
+ return flags;
+ }
+}
+
#endif /* __NTDLL_UNIX_PRIVATE_H */
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/283
More information about the wine-devel
mailing list