Skip to content

Commit

Permalink
fix: writable page should not be frozen (#142)
Browse files Browse the repository at this point in the history
* fix: writable page should not be frozen

* fix: enabled in version 1 and beyond only

* test: add tests for different version0/version1
  • Loading branch information
mohanson authored Apr 1, 2021
1 parent 0c5fd83 commit 189d097
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 5 deletions.
4 changes: 3 additions & 1 deletion src/machine/elf_adaptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn parse_elf_v1(program: &Bytes) -> Result<goblin_v034::elf::Elf, Error> {
}

/// Converts goblin's ELF flags into RISC-V flags
pub fn convert_flags(p_flags: u32) -> Result<u8, Error> {
pub fn convert_flags(p_flags: u32, allow_freeze_writable: bool) -> Result<u8, Error> {
let readable = p_flags & PF_R != 0;
let writable = p_flags & PF_W != 0;
let executable = p_flags & PF_X != 0;
Expand All @@ -27,6 +27,8 @@ pub fn convert_flags(p_flags: u32) -> Result<u8, Error> {
}
if executable {
Ok(FLAG_EXECUTABLE | FLAG_FREEZED)
} else if writable && !allow_freeze_writable {
Ok(0)
} else {
Ok(FLAG_FREEZED)
}
Expand Down
5 changes: 3 additions & 2 deletions src/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ pub trait SupportMachine: CoreMachine {
if Self::REG::BITS != elf.header.container {
return Err(Error::InvalidElfBits);
}
let version = self.version();
let program_headers = &elf.program_headers;
let mut bytes: u64 = 0;
for program_header in program_headers {
Expand All @@ -110,11 +111,11 @@ pub trait SupportMachine: CoreMachine {
self.memory_mut().init_pages(
aligned_start,
size,
elf_adaptor::convert_flags(program_header.p_flags)?,
elf_adaptor::convert_flags(program_header.p_flags, version < VERSION1)?,
Some(program.slice(slice_start as usize..slice_end as usize)),
padding_start,
)?;
if self.version() < VERSION1 {
if version < VERSION1 {
self.memory_mut()
.store_byte(aligned_start, padding_start, 0)?;
}
Expand Down
Binary file added tests/programs/writable_page
Binary file not shown.
7 changes: 7 additions & 0 deletions tests/programs/writable_page.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <stdint.h>

uint8_t buffer[4096] __attribute__((aligned(4096))) = {1, 2};

int main() {
return buffer[0] + buffer[1] - 3;
}
99 changes: 99 additions & 0 deletions tests/programs/writable_page.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@

writable_page: file format elf64-littleriscv
writable_page
architecture: riscv:rv64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00000000000100c8

Program Header:
LOAD off 0x0000000000000000 vaddr 0x0000000000010000 paddr 0x0000000000010000 align 2**12
filesz 0x00000000000004ce memsz 0x00000000000004ce flags r-x
LOAD off 0x00000000000004d0 vaddr 0x00000000000114d0 paddr 0x00000000000114d0 align 2**12
filesz 0x0000000000002290 memsz 0x00000000000022c8 flags rw-

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000041e 00000000000100b0 00000000000100b0 000000b0 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .eh_frame 00000004 00000000000114d0 00000000000114d0 000004d0 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .init_array 00000010 00000000000114d8 00000000000114d8 000004d8 2**3
CONTENTS, ALLOC, LOAD, DATA
3 .fini_array 00000008 00000000000114e8 00000000000114e8 000004e8 2**3
CONTENTS, ALLOC, LOAD, DATA
4 .data 00001748 0000000000012000 0000000000012000 00001000 2**12
CONTENTS, ALLOC, LOAD, DATA
5 .sdata 00000018 0000000000013748 0000000000013748 00002748 2**3
CONTENTS, ALLOC, LOAD, DATA
6 .bss 00000038 0000000000013760 0000000000013760 00002760 2**3
ALLOC
7 .comment 00000011 0000000000000000 0000000000000000 00002760 2**0
CONTENTS, READONLY
8 .riscv.attributes 00000029 0000000000000000 0000000000000000 00002771 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000000100b0 l d .text 0000000000000000 .text
00000000000114d0 l d .eh_frame 0000000000000000 .eh_frame
00000000000114d8 l d .init_array 0000000000000000 .init_array
00000000000114e8 l d .fini_array 0000000000000000 .fini_array
0000000000012000 l d .data 0000000000000000 .data
0000000000013748 l d .sdata 0000000000000000 .sdata
0000000000013760 l d .bss 0000000000000000 .bss
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l d .riscv.attributes 0000000000000000 .riscv.attributes
0000000000000000 l df *ABS* 0000000000000000 __call_atexit.c
00000000000100b0 l F .text 0000000000000018 register_fini
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
00000000000114d0 l O .eh_frame 0000000000000000
000000000001010c l F .text 0000000000000000 deregister_tm_clones
0000000000010130 l F .text 0000000000000000 register_tm_clones
000000000001015c l F .text 0000000000000000 __do_global_dtors_aux
0000000000013760 l O .bss 0000000000000001 completed.5470
00000000000114e8 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry
0000000000010198 l F .text 0000000000000000 frame_dummy
0000000000013768 l O .bss 0000000000000030 object.5475
00000000000114e0 l O .init_array 0000000000000000 __frame_dummy_init_array_entry
0000000000000000 l df *ABS* 0000000000000000 main.c
0000000000000000 l df *ABS* 0000000000000000 exit.c
0000000000000000 l df *ABS* 0000000000000000 impure.c
0000000000013000 l O .data 0000000000000748 impure_data
0000000000000000 l df *ABS* 0000000000000000 init.c
0000000000000000 l df *ABS* 0000000000000000 fini.c
0000000000000000 l df *ABS* 0000000000000000 atexit.c
0000000000000000 l df *ABS* 0000000000000000 __atexit.c
0000000000000000 l df *ABS* 0000000000000000 sys_exit.c
0000000000000000 l df *ABS* 0000000000000000 errno.c
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
00000000000114d0 l O .eh_frame 0000000000000000 __FRAME_END__
0000000000000000 l df *ABS* 0000000000000000
00000000000114f0 l .fini_array 0000000000000000 __fini_array_end
00000000000114e8 l .fini_array 0000000000000000 __fini_array_start
00000000000114e8 l .init_array 0000000000000000 __init_array_end
00000000000114d4 l .eh_frame 0000000000000000 __preinit_array_end
00000000000114d8 l .init_array 0000000000000000 __init_array_start
00000000000114d4 l .eh_frame 0000000000000000 __preinit_array_start
0000000000012f98 g *ABS* 0000000000000000 __global_pointer$
00000000000104c6 g F .text 0000000000000008 __errno
0000000000013748 g .sdata 0000000000000000 __SDATA_BEGIN__
0000000000013748 g O .sdata 0000000000000000 .hidden __TMC_END__
0000000000013750 g O .sdata 0000000000000000 .hidden __dso_handle
0000000000013748 g O .sdata 0000000000000008 _global_impure_ptr
000000000001020e g F .text 000000000000006a __libc_init_array
00000000000103e2 g F .text 0000000000000034 __libc_fini_array
0000000000010322 g F .text 00000000000000c0 __call_exitprocs
00000000000100c8 g F .text 0000000000000044 _start
0000000000010422 g F .text 0000000000000078 __register_exitproc
0000000000012000 g O .data 0000000000001000 buffer
0000000000013798 g .bss 0000000000000000 __BSS_END__
0000000000013760 g .bss 0000000000000000 __bss_start
0000000000010278 g F .text 00000000000000aa memset
00000000000101c2 g F .text 000000000000002c main
0000000000010416 g F .text 000000000000000c atexit
0000000000013758 g O .sdata 0000000000000008 _impure_ptr
0000000000012000 g .data 0000000000000000 __DATA_BEGIN__
0000000000013760 g .sdata 0000000000000000 _edata
0000000000013798 g .bss 0000000000000000 _end
00000000000101ee g F .text 0000000000000020 exit
000000000001049a g F .text 000000000000002c _exit


28 changes: 26 additions & 2 deletions tests/test_versions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ use ckb_vm::{
asm::{AsmCoreMachine, AsmMachine},
VERSION0, VERSION1,
},
DefaultCoreMachine, DefaultMachine, DefaultMachineBuilder, Error, SparseMemory, WXorXMemory,
ISA_IMC,
memory::FLAG_FREEZED,
CoreMachine, DefaultCoreMachine, DefaultMachine, DefaultMachineBuilder, Error, Memory,
SparseMemory, WXorXMemory, ISA_IMC, RISCV_PAGESIZE,
};
use std::fs::File;
use std::io::Read;
Expand Down Expand Up @@ -449,3 +450,26 @@ pub fn test_aot_version1_unaligned64() {
assert!(result.is_ok());
assert_eq!(result.unwrap(), 0);
}

#[test]
pub fn test_asm_version0_writable_page() {
let mut machine = create_asm_machine("writable_page".to_string(), VERSION0);
// 0x12000 is the address of the variable "buffer", which can be found from the dump file.
let page_index = 0x12000 / RISCV_PAGESIZE as u64;
let flag = machine.machine.memory_mut().fetch_flag(page_index).unwrap();
assert_eq!(flag, FLAG_FREEZED);
let result = machine.run();
assert!(result.is_ok());
assert_eq!(result.unwrap(), 0);
}

#[test]
pub fn test_asm_version1_writable_page() {
let mut machine = create_asm_machine("writable_page".to_string(), VERSION1);
let page_index = 0x12000 / RISCV_PAGESIZE as u64;
let flag = machine.machine.memory_mut().fetch_flag(page_index).unwrap();
assert_eq!(flag, 0);
let result = machine.run();
assert!(result.is_ok());
assert_eq!(result.unwrap(), 0);
}

0 comments on commit 189d097

Please sign in to comment.