Refactor copying data to userspace
This commit is contained in:
parent
14a459bf37
commit
25de53f768
@ -305,6 +305,34 @@ pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
// Split a memory region ptr..ptr + len into three parts:
|
||||
// +--------+
|
||||
// | small0 | Chunk smaller than 8 bytes
|
||||
// +--------+
|
||||
// | big | Chunk 8-byte aligned, and size a multiple of 8 bytes
|
||||
// +--------+
|
||||
// | small1 | Chunk smaller than 8 bytes
|
||||
// +--------+
|
||||
fn region_as_aligned_chunks(ptr: *const u8, len: usize) -> (u8, usize, u8) {
|
||||
let small0_size = (8 - ptr as usize % 8) as u8;
|
||||
let small1_size = ((len - small0_size as usize) % 8) as u8;
|
||||
let big_size = len - small0_size as usize - small1_size as usize;
|
||||
|
||||
(small0_size, big_size, small1_size)
|
||||
}
|
||||
|
||||
unsafe fn copy_quadwords(src: *const u8, dst: *mut u8, len: usize) {
|
||||
unsafe {
|
||||
asm!(
|
||||
"rep movsq (%rsi), (%rdi)",
|
||||
inout("rcx") len / 8 => _,
|
||||
inout("rdi") dst => _,
|
||||
inout("rsi") src => _,
|
||||
options(att_syntax, nostack, preserves_flags)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies `len` bytes of data from enclave pointer `src` to userspace `dst`
|
||||
///
|
||||
/// This function mitigates stale data vulnerabilities by ensuring all writes to untrusted memory are either:
|
||||
@ -343,17 +371,6 @@ unsafe fn copy_bytewise_to_userspace(src: *const u8, dst: *mut u8, len: usize) {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn copy_aligned_quadwords_to_userspace(src: *const u8, dst: *mut u8, len: usize) {
|
||||
unsafe {
|
||||
asm!(
|
||||
"rep movsq (%rsi), (%rdi)",
|
||||
inout("rcx") len / 8 => _,
|
||||
inout("rdi") dst => _,
|
||||
inout("rsi") src => _,
|
||||
options(att_syntax, nostack, preserves_flags)
|
||||
);
|
||||
}
|
||||
}
|
||||
assert!(!src.is_null());
|
||||
assert!(!dst.is_null());
|
||||
assert!(is_enclave_range(src, len));
|
||||
@ -370,7 +387,7 @@ unsafe fn copy_aligned_quadwords_to_userspace(src: *const u8, dst: *mut u8, len:
|
||||
} else if len % 8 == 0 && dst as usize % 8 == 0 {
|
||||
// Copying 8-byte aligned quadwords: copy quad word per quad word
|
||||
unsafe {
|
||||
copy_aligned_quadwords_to_userspace(src, dst, len);
|
||||
copy_quadwords(src, dst, len);
|
||||
}
|
||||
} else {
|
||||
// Split copies into three parts:
|
||||
@ -381,20 +398,16 @@ unsafe fn copy_aligned_quadwords_to_userspace(src: *const u8, dst: *mut u8, len:
|
||||
// +--------+
|
||||
// | small1 | Chunk smaller than 8 bytes
|
||||
// +--------+
|
||||
let (small0_size, big_size, small1_size) = region_as_aligned_chunks(dst, len);
|
||||
|
||||
unsafe {
|
||||
// Copy small0
|
||||
let small0_size = (8 - dst as usize % 8) as u8;
|
||||
let small0_src = src;
|
||||
let small0_dst = dst;
|
||||
copy_bytewise_to_userspace(small0_src as _, small0_dst, small0_size as _);
|
||||
copy_bytewise_to_userspace(src, dst, small0_size as _);
|
||||
|
||||
// Copy big
|
||||
let small1_size = ((len - small0_size as usize) % 8) as u8;
|
||||
let big_size = len - small0_size as usize - small1_size as usize;
|
||||
let big_src = src.offset(small0_size as _);
|
||||
let big_dst = dst.offset(small0_size as _);
|
||||
copy_aligned_quadwords_to_userspace(big_src as _, big_dst, big_size);
|
||||
copy_quadwords(big_src as _, big_dst, big_size);
|
||||
|
||||
// Copy small1
|
||||
let small1_src = src.offset(big_size as isize + small0_size as isize);
|
||||
|
Loading…
Reference in New Issue
Block a user