Skip to content

Commit cbca568

Browse files
committed
Auto merge of rust-lang#76345 - okready:sgx-mem-range-overflow-checks, r=joshtriplett
Add is_enclave_range/is_user_range overflow checks Fixes rust-lang#76343. This adds overflow checking to `is_enclave_range` and `is_user_range` in `sgx::os::fortanix_sgx::mem` in order to mitigate possible security issues with enclave code. It also accounts for an edge case where the memory range provided ends exactly at the end of the address space, where calculating `p + len` would overflow back to zero despite the range potentially being valid.
2 parents 35dbef2 + c989de5 commit cbca568

File tree

1 file changed

+34
-8
lines changed
  • library/std/src/sys/sgx/abi

1 file changed

+34
-8
lines changed

library/std/src/sys/sgx/abi/mem.rs

+34-8
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,46 @@ pub fn image_base() -> u64 {
4747

4848
/// Returns `true` if the specified memory range is in the enclave.
4949
///
50-
/// `p + len` must not overflow.
50+
/// For safety, this function also checks whether the range given overflows,
51+
/// returning `false` if so.
5152
#[unstable(feature = "sgx_platform", issue = "56975")]
5253
pub fn is_enclave_range(p: *const u8, len: usize) -> bool {
53-
let start = p as u64;
54-
let end = start + (len as u64);
55-
start >= image_base() && end <= image_base() + (unsafe { ENCLAVE_SIZE } as u64) // unsafe ok: link-time constant
54+
let start = p as usize;
55+
56+
// Subtract one from `len` when calculating `end` in case `p + len` is
57+
// exactly at the end of addressable memory (`p + len` would overflow, but
58+
// the range is still valid).
59+
let end = if len == 0 {
60+
start
61+
} else if let Some(end) = start.checked_add(len - 1) {
62+
end
63+
} else {
64+
return false;
65+
};
66+
67+
let base = image_base() as usize;
68+
start >= base && end <= base + (unsafe { ENCLAVE_SIZE } - 1) // unsafe ok: link-time constant
5669
}
5770

5871
/// Returns `true` if the specified memory range is in userspace.
5972
///
60-
/// `p + len` must not overflow.
73+
/// For safety, this function also checks whether the range given overflows,
74+
/// returning `false` if so.
6175
#[unstable(feature = "sgx_platform", issue = "56975")]
6276
pub fn is_user_range(p: *const u8, len: usize) -> bool {
63-
let start = p as u64;
64-
let end = start + (len as u64);
65-
end <= image_base() || start >= image_base() + (unsafe { ENCLAVE_SIZE } as u64) // unsafe ok: link-time constant
77+
let start = p as usize;
78+
79+
// Subtract one from `len` when calculating `end` in case `p + len` is
80+
// exactly at the end of addressable memory (`p + len` would overflow, but
81+
// the range is still valid).
82+
let end = if len == 0 {
83+
start
84+
} else if let Some(end) = start.checked_add(len - 1) {
85+
end
86+
} else {
87+
return false;
88+
};
89+
90+
let base = image_base() as usize;
91+
end < base || start > base + (unsafe { ENCLAVE_SIZE } - 1) // unsafe ok: link-time constant
6692
}

0 commit comments

Comments
 (0)