Skip to content

Commit

Permalink
Couple EMM with rt initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
ClawSeven committed Aug 29, 2023
1 parent 4ef6ca2 commit 60caea5
Show file tree
Hide file tree
Showing 10 changed files with 405 additions and 45 deletions.
41 changes: 41 additions & 0 deletions sgx_trts/src/edmm/mem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ mod hw {
use crate::edmm::perm;
use crate::edmm::trim;
use crate::elf::program::Type;
use crate::emm::flags::AllocFlags;
use crate::emm::range::RM;
use crate::enclave::parse;
use crate::enclave::MmLayout;
use crate::feature::{SysFeatures, Version};
Expand Down Expand Up @@ -190,6 +192,45 @@ mod hw {
Ok(())
}

pub fn init_segment_emas() -> SgxResult {
let elf = parse::new_elf()?;
let text_relo = parse::has_text_relo()?;

let base = MmLayout::image_base();
for phdr in elf.program_iter() {
let typ = phdr.get_type().unwrap_or(Type::Null);

if typ == Type::Load {
let mut perm = ProtFlags::R;
let start = base + trim_to_page!(phdr.virtual_addr() as usize);
let end =
base + round_to_page!(phdr.virtual_addr() as usize + phdr.mem_size() as usize);

if phdr.flags().is_write() || text_relo {
perm |= ProtFlags::W;
}
if phdr.flags().is_execute() {
perm |= ProtFlags::X;
}

let mut range_manage = RM.get().unwrap().lock();
range_manage.init_static_region(
start,
end - start,
AllocFlags::SYSTEM,
PageInfo {
typ: PageType::Reg,
prot: perm,
},
None,
None,
)?;
}
}

Ok(())
}

fn modify_perm(addr: usize, count: usize, perm: u8) -> SgxResult {
let pages = PageRange::new(
addr,
Expand Down
17 changes: 17 additions & 0 deletions sgx_trts/src/emm/alloc.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License..

use core::alloc::{AllocError, Allocator, Layout};
use core::ptr::NonNull;

Expand Down
1 change: 1 addition & 0 deletions sgx_trts/src/emm/bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License..

use alloc::boxed::Box;
use alloc::vec;
use core::alloc::Allocator;
Expand Down
21 changes: 20 additions & 1 deletion sgx_trts/src/emm/ema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl EMA {
alloc: Alloc,
) -> SgxResult<Self> {
// check alloc flags' eligibility
AllocFlags::try_from(alloc_flags.bits())?;
// AllocFlags::try_from(alloc_flags.bits())?;

if start != 0
&& length != 0
Expand Down Expand Up @@ -576,6 +576,25 @@ impl EMA {
(addr >= self.start) && (addr < self.start + self.length)
}

pub fn set_eaccept_map_full(&mut self) -> SgxResult {
if self.eaccept_map.is_none() {
let eaccept_map = match self.alloc {
Alloc::Reserve => {
let page_num = self.length >> SE_PAGE_SHIFT;
BitArray::new(page_num, Alloc::Reserve)?
}
Alloc::Static => {
let page_num = self.length >> SE_PAGE_SHIFT;
BitArray::new(page_num, Alloc::Static)?
}
};
self.eaccept_map = Some(eaccept_map);
} else {
self.eaccept_map.as_mut().unwrap().set_full();
}
Ok(())
}

fn set_flags(&mut self, flags: AllocFlags) {
self.alloc_flags = flags;
}
Expand Down
25 changes: 1 addition & 24 deletions sgx_trts/src/emm/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
// under the License..

use bitflags::bitflags;
use sgx_types::error::{SgxResult, SgxStatus};

bitflags! {
pub struct AllocFlags: u32 {
Expand All @@ -26,28 +25,6 @@ bitflags! {
const GROWSDOWN = 0b00010000;
const GROWSUP = 0b00100000;
const FIXED = 0b01000000;
}
}

impl AllocFlags {
pub fn try_from(value: u32) -> SgxResult<Self> {
match value {
0b0000_0001 => Ok(Self::RESERVED),
0b0000_0010 => Ok(Self::COMMIT_NOW),
0b0000_0100 => Ok(Self::COMMIT_ON_DEMAND),
0b0001_0000 => Ok(Self::GROWSDOWN),
0b0010_0000 => Ok(Self::GROWSUP),
0b0100_0000 => Ok(Self::FIXED),
0b0001_0001 => Ok(Self::RESERVED | Self::GROWSDOWN),
0b0010_0001 => Ok(Self::RESERVED | Self::GROWSUP),
0b0100_0001 => Ok(Self::RESERVED | Self::FIXED),
0b0001_0010 => Ok(Self::COMMIT_NOW | Self::GROWSDOWN),
0b0010_0010 => Ok(Self::COMMIT_NOW | Self::GROWSUP),
0b0100_0010 => Ok(Self::COMMIT_NOW | Self::FIXED),
0b0001_0100 => Ok(Self::COMMIT_ON_DEMAND | Self::GROWSDOWN),
0b0010_0100 => Ok(Self::COMMIT_ON_DEMAND | Self::GROWSUP),
0b0100_0100 => Ok(Self::COMMIT_ON_DEMAND | Self::FIXED),
_ => Err(SgxStatus::InvalidParameter),
}
const SYSTEM = 0b10000000;
}
}
152 changes: 152 additions & 0 deletions sgx_trts/src/emm/init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License..

use sgx_types::error::SgxResult;

use crate::arch::{Layout, LayoutEntry};
use crate::edmm::mem::init_segment_emas;
use crate::edmm::{PageInfo, PageType, ProtFlags};
use crate::emm::flags::AllocFlags;
use crate::emm::interior::Alloc;
use crate::emm::range::{RangeType, EMA_PROT_MASK};
use crate::enclave::MmLayout;
use crate::{arch, emm::range::RM};

use super::{interior::init_alloc, range::init_range_manage, user::init_user_range};

pub fn init_emm(user_start: usize, user_end: usize) {
// check user_start not equals to 0
init_user_range(user_start, user_end);
init_range_manage();
init_alloc();
}

pub fn init_rts_emas() -> SgxResult {
init_segment_emas()?;
init_rts_contexts_emas(arch::Global::get().layout_table(), 0)?;
Ok(())
}

fn init_rts_contexts_emas(table: &[Layout], offset: usize) -> SgxResult {
unsafe {
for (i, layout) in table.iter().enumerate() {
if is_group_id!(layout.group.id) {
let mut step = 0_usize;
for _ in 0..layout.group.load_times {
step += layout.group.load_step as usize;
init_rts_contexts_emas(&table[i - layout.group.entry_count as usize..i], step)?;
}
} else {
build_rts_context_emas(&layout.entry, offset)?;
}
}
Ok(())
}
}

fn build_rts_context_emas(entry: &LayoutEntry, offset: usize) -> SgxResult {
let rva = offset + (entry.rva as usize);
assert!(is_page_aligned!(rva));

// TODO: not sure get_enclave_base() equal to elrange_base or image_base
let addr = MmLayout::elrange_base() + (rva as usize);
let size = (entry.page_count << arch::SE_PAGE_SHIFT) as usize;
let mut range_manage = RM.get().unwrap().lock();

// entry is guard page or has EREMOVE, build a reserved ema
if (entry.si_flags == 0) || (entry.attributes & arch::PAGE_ATTR_EREMOVE != 0) {
range_manage.init_static_region(
addr,
size,
AllocFlags::RESERVED | AllocFlags::SYSTEM,
PageInfo {
typ: PageType::None,
prot: ProtFlags::NONE,
},
None,
None,
)?;
return Ok(());
}

let post_remove = (entry.attributes & arch::PAGE_ATTR_POST_REMOVE) != 0;
let post_add = (entry.attributes & arch::PAGE_ATTR_POST_ADD) != 0;
let static_min = (entry.attributes & arch::PAGE_ATTR_EADD) != 0;

if post_remove {
// TODO: maybe AllocFlags need more flags or PageType is not None
range_manage.init_static_region(
addr,
size,
AllocFlags::SYSTEM,
PageInfo {
typ: PageType::None,
prot: ProtFlags::R | ProtFlags::W,
},
None,
None,
)?;

range_manage.dealloc(addr, size, RangeType::Rts)?;
}

if post_add {
let commit_direction = if entry.id == arch::LAYOUT_ID_STACK_MAX
|| entry.id == arch::LAYOUT_ID_STACK_DYN_MAX
|| entry.id == arch::LAYOUT_ID_STACK_DYN_MIN
{
AllocFlags::GROWSDOWN
} else {
AllocFlags::GROWSUP
};

// TODO: revise alloc and not use int
range_manage.alloc_inner(
Some(addr),
size,
AllocFlags::COMMIT_ON_DEMAND
| commit_direction
| AllocFlags::SYSTEM
| AllocFlags::FIXED,
PageInfo {
typ: PageType::Reg,
prot: ProtFlags::R | ProtFlags::W,
},
None,
None,
RangeType::Rts,
Alloc::Reserve,
)?;
} else if static_min {
let info = if entry.id == arch::LAYOUT_ID_TCS {
PageInfo {
typ: PageType::Tcs,
prot: ProtFlags::NONE,
}
} else {
PageInfo {
typ: PageType::Reg,
prot: ProtFlags::from_bits_truncate(
(entry.si_flags as usize & EMA_PROT_MASK) as u8,
),
}
};
range_manage.init_static_region(addr, size, AllocFlags::SYSTEM, info, None, None)?;
}

Ok(())
}
9 changes: 1 addition & 8 deletions sgx_trts/src/emm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,13 @@
// specific language governing permissions and limitations
// under the License..

use self::{interior::init_alloc, range::init_range_manage, user::init_user_range};

pub(crate) mod alloc;
pub(crate) mod bitmap;
pub(crate) mod ema;
pub(crate) mod flags;
pub(crate) mod init;
#[cfg(not(any(feature = "sim", feature = "hyper")))]
pub(crate) mod interior;
mod pfhandler;
pub(crate) mod range;
pub(crate) mod user;

fn init_emm(user_start: usize, user_end: usize) {
init_user_range(user_start, user_end);
init_range_manage();
init_alloc();
}
Loading

0 comments on commit 60caea5

Please sign in to comment.