Skip to content

Commit

Permalink
Added some hack to simulate seccomp/bpf Windows syscalls handling in …
Browse files Browse the repository at this point in the history
…proton
  • Loading branch information
ptitSeb committed Jan 17, 2025
1 parent 03204f7 commit 21c0a2e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
12 changes: 12 additions & 0 deletions src/emu/x64syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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?
Expand Down Expand Up @@ -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";
Expand Down
10 changes: 7 additions & 3 deletions src/tools/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand All @@ -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);

Expand Down

0 comments on commit 21c0a2e

Please sign in to comment.