about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-01-17 12:24:10 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-01-17 12:24:10 +0100
commit21c0a2e7d762c4b42f80f8ee87a43bb99f510e0a (patch)
tree87fc6ca9a2785f6b1d160320d0870d7258c1380b /src
parent03204f709e4586ae0a9950f3e6a7e1158b4a3f66 (diff)
downloadbox64-21c0a2e7d762c4b42f80f8ee87a43bb99f510e0a.tar.gz
box64-21c0a2e7d762c4b42f80f8ee87a43bb99f510e0a.zip
Added some hack to simulate seccomp/bpf Windows syscalls handling in proton
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64syscall.c12
-rw-r--r--src/tools/bridge.c10
2 files changed, 19 insertions, 3 deletions
diff --git a/src/emu/x64syscall.c b/src/emu/x64syscall.c
index ee3e7a8c..a912afcb 100644
--- a/src/emu/x64syscall.c
+++ b/src/emu/x64syscall.c
@@ -34,6 +34,7 @@
 #include "callback.h"
 #include "signals.h"
 #include "x64tls.h"
+#include "elfloader.h"
 
 typedef struct x64_sigaction_s x64_sigaction_t;
 typedef struct x64_stack_s x64_stack_t;
@@ -294,6 +295,7 @@ static const scwrap_t syscallwrap[] = {
     //[317] = {__NR_seccomp, 3},
     [318] = {__NR_getrandom, 3},
     [319] = {__NR_memfd_create, 2},
+    //[323] = {__NR_userfaultfd, 1}, //disable for now
     [324] = {__NR_membarrier, 2},
     #ifdef __NR_copy_file_range
     // TODO: call back if unavailable?
@@ -432,6 +434,16 @@ void EXPORT x64Syscall(x64emu_t *emu)
 {
     RESET_FLAGS(emu);
     uint32_t s = R_EAX; // EAX? (syscalls only go up to 547 anyways)
+    // check if it's a wine process, then filter the syscall (simulate SECCMP)
+    if(box64_wine && !box64_is32bits) {
+        //64bits only here...
+        uintptr_t ret_addr = R_RIP-2;
+        if(ret_addr<0x700000000000LL && (my_context->signals[SIGSYS]>2) && !FindElfAddress(my_context, ret_addr)) {
+            // not a linux elf, not a syscall to setup x86_64 arch. Signal SIGSYS
+            emit_signal(emu, SIGSYS, (void*)ret_addr, R_EAX&0xffff);  // what are the parameters?
+            return;
+        }
+    }
     int log = 0;
     char t_buff[256] = "\0";
     char t_buffret[128] = "\0";
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index b2f78d86..3a995e31 100644
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -42,9 +42,9 @@ brick_t* NewBrick(void* old)
     brick_t* ret = (brick_t*)box_calloc(1, sizeof(brick_t));
     if(old)
         old = old + NBRICK * sizeof(onebridge_t);
-    void* ptr = box_mmap(old, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | 0x40 | MAP_ANONYMOUS, -1, 0); // 0x40 is MAP_32BIT
+    void* ptr = box_mmap(old, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | ((!box64_is32bits && box64_wine)?0:0x40) | MAP_ANONYMOUS, -1, 0); // 0x40 is MAP_32BIT
     if(ptr == MAP_FAILED)
-        ptr = box_mmap(NULL, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | 0x40 | MAP_ANONYMOUS, -1, 0);
+        ptr = box_mmap(NULL, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | ((!box64_is32bits && box64_wine)?0:0x40) | MAP_ANONYMOUS, -1, 0);
     if(ptr == MAP_FAILED) {
         printf_log(LOG_NONE, "Warning, cannot allocate 0x%lx aligned bytes for bridge, will probably crash later\n", NBRICK*sizeof(onebridge_t));
     }
@@ -57,7 +57,11 @@ brick_t* NewBrick(void* old)
 bridge_t *NewBridge()
 {
     bridge_t *b = (bridge_t*)box_calloc(1, sizeof(bridge_t));
-    b->head = NewBrick(NULL);
+    // before enable seccomp and bpf fileter, proton check if "syscall" address (from libc) is > 0x700000000000
+    // it also test if an internal symbol "sc_seccomp" address's is also > 0x700000000000 before enabling seccomp syscall filter.
+    // This hack  allow the test to pass, but only if the system has at least 47bits address space.
+    // it will not work on 39bits address space and will need more hacks there
+    b->head = NewBrick((!box64_is32bits && box64_wine)?((void*)0x700000000000LL):NULL);
     b->last = b->head;
     b->bridgemap = kh_init(bridgemap);