Last active
May 31, 2020 18:51
-
-
Save mmtrt/5ee395e88d9a45b6af2f59f2016f4a6b to your computer and use it in GitHub Desktop.
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/thread.c b/dlls/ntdll/thread.c | |
index c5b2008e44..96ca266921 100644 | |
--- a/dlls/ntdll/thread.c | |
+++ b/dlls/ntdll/thread.c | |
@@ -268,6 +268,77 @@ static void set_process_name( int argc, char *argv[] ) | |
} | |
+#ifdef __i386__ | |
+#include <asm/ldt.h> | |
+#include <linux/audit.h> | |
+#include <linux/filter.h> | |
+#include <linux/seccomp.h> | |
+#include <linux/unistd.h> | |
+#include <sys/prctl.h> | |
+#include <errno.h> | |
+ | |
+static void sigsys_handler( int signal, siginfo_t *siginfo, void *sigcontext ) | |
+{ | |
+ ucontext_t *ctx = sigcontext; | |
+ | |
+ WINE_ERR( "SIGSYS (%d)\n", ctx->uc_mcontext.gregs[REG_EAX] ); | |
+ | |
+ // FIXME Relay to actual Nt syscall. | |
+ | |
+ ctx->uc_mcontext.gregs[REG_EAX] = 0; | |
+} | |
+ | |
+// FIXME All of this code is i386 Linux-specific. It may want to live in | |
+// signal_i386.c. | |
+void seccomp_init(void) | |
+{ | |
+ int ret; | |
+ char *tcbhead; | |
+ struct sigaction sig_act; | |
+ // FIXME Allocate a range of syscall numbers for Wine, e.g. 1024+. This | |
+ // will be necessary to distinguish Linux syscall numbers from Wine | |
+ // syscall numbers. | |
+ struct sock_filter filter[] = { | |
+ { BPF_LD | BPF_W | BPF_ABS, 0, 0, 0 }, | |
+ { BPF_JMP | BPF_JEQ, 1, 0, 173 }, | |
+ { BPF_RET, 0, 0, SECCOMP_RET_ALLOW }, | |
+ { BPF_LD | BPF_W | BPF_ABS, 0, 0, 4 }, | |
+ { BPF_JMP | BPF_JEQ, 1, 0, AUDIT_ARCH_X86_64 }, | |
+ { BPF_RET, 0, 0, SECCOMP_RET_ALLOW }, | |
+ { BPF_RET, 0, 0, SECCOMP_RET_TRAP } | |
+ }; | |
+ struct sock_fprog prog = { 7, filter }; | |
+ | |
+ // FIXME There is no way to remove a seccomp upon execve. This should not | |
+ // have bad effects on non-Wine programs, provided we fix the syscall | |
+ // numbering, but we may be adding the same seccomp filter multiple | |
+ // times unnecessarily. | |
+ ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | |
+ TRACE( "prctl(SET_NO_NEW_PRIVS) = %d, %d\n", ret, errno ); | |
+ prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0); | |
+ TRACE( "prctl(SET_SECCOMP) = %d, %d\n", ret, errno ); | |
+ | |
+ sig_act.sa_mask = server_block_set; | |
+ sig_act.sa_flags = SA_SIGINFO | SA_RESTART; | |
+#ifdef SA_ONSTACK | |
+ sig_act.sa_flags |= SA_ONSTACK; | |
+#endif | |
+ sig_act.sa_sigaction = sigsys_handler; | |
+ ret = sigaction( SIGSYS, &sig_act, NULL ); | |
+ TRACE( "sigaction(SIGSYS) = %d\n", ret ); | |
+ | |
+ asm ("mov %%gs:0, %0" : "=r" (tcbhead)); | |
+ TRACE( "gs:0 = %p\n", tcbhead ); | |
+ | |
+ // FIXME Requires a patched version of glibc to expand the reserved size | |
+ // at the top of (struct pthread). Upstream glibc only reserves 0x60 | |
+ // bytes on i386, and we require at least 0x68 bytes. The code below | |
+ // assumes at least 0x6C bytes are reserved. | |
+ *(uint64_t *)(tcbhead + 0x60) = (uintptr_t)(tcbhead + 0x68); | |
+} | |
+#endif | |
+ | |
+ | |
/*********************************************************************** | |
* thread_init | |
* | |
@@ -497,6 +497,11 @@ TEB *thread_init(void) | |
unix_funcs->get_paths( &build_dir, &data_dir, &config_dir ); | |
set_process_name( __wine_main_argc, __wine_main_argv ); | |
fill_cpu_info(); | |
+ | |
+#ifdef __i386__ | |
+ seccomp_init(); | |
+#endif | |
+ | |
return teb; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment