From dd8d3fb9d1e94aa5131c833db63ef24f9e3f1e5e Mon Sep 17 00:00:00 2001 From: Theodore Dubois Date: Wed, 1 Jan 2020 19:27:08 -0800 Subject: [PATCH] Fix race condition in mem_segv_reason There's a brief delay between the page fault and calling mem_segv_reason, and in that window the access could become valid. --- emu/cpu.h | 1 - emu/memory.c | 8 ++------ emu/memory.h | 2 +- jit/gadgets-aarch64/memory.S | 6 ------ jit/gadgets-x86_64/memory.S | 5 ----- jit/offsets.c | 1 - kernel/calls.c | 2 +- 7 files changed, 4 insertions(+), 21 deletions(-) diff --git a/emu/cpu.h b/emu/cpu.h index 4409b117b3..833cdfd267 100644 --- a/emu/cpu.h +++ b/emu/cpu.h @@ -144,7 +144,6 @@ struct cpu_state { // for the page fault handler addr_t segfault_addr; - uint8_t segfault_type; dword_t trapno; }; diff --git a/emu/memory.c b/emu/memory.c index 7c770c72fc..0f618c1f59 100644 --- a/emu/memory.c +++ b/emu/memory.c @@ -285,15 +285,11 @@ void *mem_ptr(struct mem *mem, addr_t addr, int type) { return entry->data->data + entry->offset + PGOFFSET(addr); } -int mem_segv_reason(struct mem *mem, addr_t addr, int type) { - assert(type == MEM_READ || type == MEM_WRITE); +int mem_segv_reason(struct mem *mem, addr_t addr) { struct pt_entry *pt = mem_pt(mem, PAGE(addr)); if (pt == NULL) return SEGV_MAPERR_; - if ((type == MEM_READ && !(pt->flags & P_READ)) || - (type == MEM_WRITE && !(pt->flags & P_WRITE))) - return SEGV_ACCERR_; - die("caught segv for valid access"); + return SEGV_ACCERR_; } size_t real_page_size; diff --git a/emu/memory.h b/emu/memory.h index 17bc35fb95..907c664716 100644 --- a/emu/memory.h +++ b/emu/memory.h @@ -113,7 +113,7 @@ int pt_copy_on_write(struct mem *src, struct mem *dst, page_t start, page_t page #define MEM_WRITE 1 // Must call with mem read-locked. void *mem_ptr(struct mem *mem, addr_t addr, int type); -int mem_segv_reason(struct mem *mem, addr_t addr, int type); +int mem_segv_reason(struct mem *mem, addr_t addr); extern size_t real_page_size; diff --git a/jit/gadgets-aarch64/memory.S b/jit/gadgets-aarch64/memory.S index 3675882fba..31f6893fc0 100644 --- a/jit/gadgets-aarch64/memory.S +++ b/jit/gadgets-aarch64/memory.S @@ -85,12 +85,6 @@ NAME(si_gadgets): segfault_\type: str _addr, [_cpu, CPU_segfault_addr] - .ifc \type,read - mov w0, MEM_READ - .else - mov w0, MEM_WRITE - .endif - strb w0, [_cpu, CPU_segfault_type] ldr eip, [_ip] mov x0, INT_GPF b jit_exit diff --git a/jit/gadgets-x86_64/memory.S b/jit/gadgets-x86_64/memory.S index 69deaab533..10a0a39789 100644 --- a/jit/gadgets-x86_64/memory.S +++ b/jit/gadgets-x86_64/memory.S @@ -79,11 +79,6 @@ segfault_\type: movl %_addr, CPU_segfault_addr(%_cpu) - .ifc \type,read - movb $MEM_READ, CPU_segfault_type(%_cpu) - .else - movb $MEM_WRITE, CPU_segfault_type(%_cpu) - .endif movl (%_ip), %_eip movl $INT_GPF, %_tmp jmp jit_exit diff --git a/jit/offsets.c b/jit/offsets.c index 3a38679385..5b082355f6 100644 --- a/jit/offsets.c +++ b/jit/offsets.c @@ -50,7 +50,6 @@ void cpu() { OFFSET(LOCAL, jit_frame, last_block); OFFSET(LOCAL, jit_frame, ret_cache); OFFSET(CPU, cpu_state, segfault_addr); - OFFSET(CPU, cpu_state, segfault_type); MACRO(MEM_READ); MACRO(MEM_WRITE); diff --git a/kernel/calls.c b/kernel/calls.c index 9d89fb668a..8326b2b696 100644 --- a/kernel/calls.c +++ b/kernel/calls.c @@ -242,7 +242,7 @@ void handle_interrupt(int interrupt) { } else if (interrupt == INT_GPF) { printk("%d page fault on 0x%x at 0x%x\n", current->pid, cpu->segfault_addr, cpu->eip); struct siginfo_ info = { - .code = mem_segv_reason(cpu->mem, cpu->segfault_addr, cpu->segfault_type), + .code = mem_segv_reason(cpu->mem, cpu->segfault_addr), .fault.addr = cpu->segfault_addr, }; deliver_signal(current, SIGSEGV_, info);