Add support for mprotect PROT_GROWSDOWN

This commit is contained in:
Hui, Chunyang 2021-10-18 11:11:55 +00:00 committed by Zongmin.Gu
parent 0eb3353b7c
commit 1745825e81
2 changed files with 24 additions and 2 deletions

@ -8,6 +8,7 @@ bitflags! {
const EXEC = 0x4;
const DEFAULT = Self::READ.bits | Self::WRITE.bits;
const ALL = Self::DEFAULT.bits | Self::EXEC.bits;
const GROWSDOWN = 0x01000000; // For x86, stack direction always grow downwards.
}
}
@ -46,8 +47,11 @@ impl VMPerms {
let mut retval = 0;
let addr = protect_range.start() as *const c_void;
let len = protect_range.size();
let prot = perms.bits() as i32;
let sgx_status = occlum_ocall_mprotect(&mut retval, addr, len, prot);
// PT_GROWSDOWN should only be applied to stack segment or a segment mapped with the MAP_GROWSDOWN flag set.
// Since the memory are managed by our own, mprotect ocall shouldn't use this flag. Otherwise, EINVAL will be thrown.
let mut prot = perms.clone();
prot.remove(VMPerms::GROWSDOWN);
let sgx_status = occlum_ocall_mprotect(&mut retval, addr, len, prot.bits() as i32);
assert!(sgx_status == sgx_status_t::SGX_SUCCESS && retval == 0);
}
}

@ -1086,6 +1086,23 @@ int test_mprotect_multiple_vmas() {
return 0;
}
int test_mprotect_grow_down() {
int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN;
void *buf = mmap(0, PAGE_SIZE * 2, PROT_NONE, flags, -1, 0);
if (buf == MAP_FAILED) {
THROW_ERROR("mmap failed");
}
// Mprotect can use PROT_GROWSDOWN on a stack segment or a segment mapped with the MAP_GROWSDOWN flag set
int ret = mprotect(buf, 2 * PAGE_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC | PROT_GROWSDOWN);
if (ret < 0) {
THROW_ERROR("mprotect failed");
}
return 0;
}
int check_file_first_four_page(char *file_path, int first_page_val, int secend_page_val,
int third_page_val, int fourth_page_val) {
int fd = open(file_path, O_RDONLY);
@ -1289,6 +1306,7 @@ static test_case_t test_cases[] = {
TEST_CASE(test_mprotect_with_invalid_prot),
TEST_CASE(test_mprotect_with_non_page_aligned_size),
TEST_CASE(test_mprotect_multiple_vmas),
TEST_CASE(test_mprotect_grow_down),
};
int main() {