From 586a00015294fee68c20ccb53a1b236c8971056e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 4 Oct 2021 17:42:15 +0100 Subject: [PATCH] Add `Protect_Flags` for `virtual.protect` --- core/mem/virtual/virtual.odin | 18 +++++++++++++----- core/mem/virtual/virtual_linux.odin | 9 +++++++-- core/mem/virtual/virtual_windows.odin | 20 ++++++++++++++++++-- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/core/mem/virtual/virtual.odin b/core/mem/virtual/virtual.odin index a78917ae1..ee314589f 100644 --- a/core/mem/virtual/virtual.odin +++ b/core/mem/virtual/virtual.odin @@ -16,12 +16,11 @@ commit :: proc(data: rawptr, size: uint) { } reserve_and_commit :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { - data = _reserve(size) or_return + data = reserve(size) or_return commit(raw_data(data), size) return } - decommit :: proc(data: rawptr, size: uint) { _decommit(data, size) } @@ -30,9 +29,18 @@ release :: proc(data: rawptr, size: uint) { _release(data, size) } -protect :: proc(data: rawptr, size: uint) -> bool { - return _protect(data, size) +Protect_Flag :: enum u32 { + Read, + Write, + Execute, } +Protect_Flags :: distinct bit_set[Protect_Flag; u32] +Protect_No_Access :: Protect_Flags{} + +protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool { + return _protect(data, size, flags) +} + @@ -73,7 +81,7 @@ memory_alloc :: proc(size: int) -> (block: ^Memory_Block, err: Allocator_Error) assert(pmblock.block.prev == nil) if (do_protection) { - protect(rawptr(uintptr(pmblock) + protect_offset), page_size) + protect(rawptr(uintptr(pmblock) + protect_offset), page_size, Protect_No_Access) } pmblock.block.size = size diff --git a/core/mem/virtual/virtual_linux.odin b/core/mem/virtual/virtual_linux.odin index df542aea1..2ee787169 100644 --- a/core/mem/virtual/virtual_linux.odin +++ b/core/mem/virtual/virtual_linux.odin @@ -86,8 +86,13 @@ _decommit :: proc(data: rawptr, size: uint) { _release :: proc(data: rawptr, size: uint) { munmap(data, size) } -_protect :: proc(data: rawptr, size: uint) -> bool { - err := mprotect(data, size, PROT_NONE) +_protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool { + pflags: c.int + pflags = PROT_NONE + if .Read in flags { pflags |= PROT_READ } + if .Write in flags { pflags |= PROT_WRITE } + if .Execute in flags { pflags |= PROT_EXEC } + err := mprotect(data, size, pflags) return err != 0 } diff --git a/core/mem/virtual/virtual_windows.odin b/core/mem/virtual/virtual_windows.odin index fb28eb117..b17e396c8 100644 --- a/core/mem/virtual/virtual_windows.odin +++ b/core/mem/virtual/virtual_windows.odin @@ -77,9 +77,25 @@ _decommit :: proc(data: rawptr, size: uint) { _release :: proc(data: rawptr, size: uint) { VirtualFree(data, 0, MEM_RELEASE) } -_protect :: proc(data: rawptr, size: uint) -> bool { +_protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool { + pflags: u32 + pflags = PAGE_NOACCESS + switch flags { + case {}: pflags = PAGE_NOACCESS + case {.Read}: pflags = PAGE_READONLY + case {.Read, .Write}: pflags = PAGE_READWRITE + case {.Write}: pflags = PAGE_WRITECOPY + case {.Execute}: pflags = PAGE_EXECUTE + case {.Execute, .Read}: pflags = PAGE_EXECUTE_READ + case {.Execute, .Read, .Write}: pflags = PAGE_EXECUTE_READWRITE + case {.Execute, .Write}: pflags = PAGE_EXECUTE_WRITECOPY + case: + return false + } + + old_protect: u32 - ok := VirtualProtect(data, size, PAGE_NOACCESS, &old_protect) + ok := VirtualProtect(data, size, pflags, &old_protect) return bool(ok) }