Skip to content

Commit 1fb0a1d

Browse files
Caduser2020Caduser2020
Caduser2020
authored and
Caduser2020
committed
#[deny(unsafe_op_in_unsafe_fn)] in sys/sgx
Run `./x.py` fmt Add reference link Fix reference link Apply review suggestions.
1 parent 4d52dc4 commit 1fb0a1d

File tree

14 files changed

+170
-119
lines changed

14 files changed

+170
-119
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ unsafe extern "C" fn tcs_init(secondary: bool) {
4545
// We need to wait until the initialization is done.
4646
BUSY => {
4747
while RELOC_STATE.load(Ordering::Acquire) == BUSY {
48-
core::arch::x86_64::_mm_pause()
48+
core::hint::spin_loop();
4949
}
5050
}
5151
// Initialization is done.

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,21 @@ impl Tls {
8787
}
8888

8989
pub unsafe fn activate(&self) -> ActiveTls<'_> {
90-
set_tls_ptr(self as *const Tls as _);
90+
// FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
91+
unsafe { set_tls_ptr(self as *const Tls as _) };
9192
ActiveTls { tls: self }
9293
}
9394

9495
#[allow(unused)]
9596
pub unsafe fn activate_persistent(self: Box<Self>) {
96-
set_tls_ptr((&*self) as *const Tls as _);
97+
// FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
98+
unsafe { set_tls_ptr((&*self) as *const Tls as _) };
9799
mem::forget(self);
98100
}
99101

100102
unsafe fn current<'a>() -> &'a Tls {
101-
&*(get_tls_ptr() as *const Tls)
103+
// FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition.
104+
unsafe { &*(get_tls_ptr() as *const Tls) }
102105
}
103106

104107
pub fn create(dtor: Option<unsafe extern "C" fn(*mut u8)>) -> Key {

library/std/src/sys/sgx/abi/usercalls/alloc.rs

+49-22
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,12 @@ pub unsafe trait UserSafe {
8989
/// * the pointed-to range is not in user memory.
9090
unsafe fn from_raw_sized(ptr: *mut u8, size: usize) -> NonNull<Self> {
9191
assert!(ptr.wrapping_add(size) >= ptr);
92-
let ret = Self::from_raw_sized_unchecked(ptr, size);
93-
Self::check_ptr(ret);
94-
NonNull::new_unchecked(ret as _)
92+
// SAFETY: The caller has guaranteed the pointer is valid
93+
let ret = unsafe { Self::from_raw_sized_unchecked(ptr, size) };
94+
unsafe {
95+
Self::check_ptr(ret);
96+
NonNull::new_unchecked(ret as _)
97+
}
9598
}
9699

97100
/// Checks if a pointer may point to `Self` in user memory.
@@ -112,7 +115,7 @@ pub unsafe trait UserSafe {
112115
let is_aligned = |p| -> bool { 0 == (p as usize) & (Self::align_of() - 1) };
113116

114117
assert!(is_aligned(ptr as *const u8));
115-
assert!(is_user_range(ptr as _, mem::size_of_val(&*ptr)));
118+
assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr })));
116119
assert!(!ptr.is_null());
117120
}
118121
}
@@ -135,11 +138,23 @@ unsafe impl<T: UserSafeSized> UserSafe for [T] {
135138
mem::align_of::<T>()
136139
}
137140

141+
/// # Safety
142+
/// Behavior is undefined if any of these conditions are violated:
143+
/// * `ptr` must be [valid] for writes of `size` many bytes, and it must be
144+
/// properly aligned.
145+
///
146+
/// [valid]: core::ptr#safety
147+
/// # Panics
148+
///
149+
/// This function panics if:
150+
///
151+
/// * the element size is not a factor of the size
138152
unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self {
139153
let elem_size = mem::size_of::<T>();
140154
assert_eq!(size % elem_size, 0);
141155
let len = size / elem_size;
142-
slice::from_raw_parts_mut(ptr as _, len)
156+
// SAFETY: The caller must uphold the safety contract for `from_raw_sized_unchecked`
157+
unsafe { slice::from_raw_parts_mut(ptr as _, len) }
143158
}
144159
}
145160

@@ -170,13 +185,15 @@ trait NewUserRef<T: ?Sized> {
170185

171186
impl<T: ?Sized> NewUserRef<*mut T> for NonNull<UserRef<T>> {
172187
unsafe fn new_userref(v: *mut T) -> Self {
173-
NonNull::new_unchecked(v as _)
188+
// SAFETY: The caller has guaranteed the pointer is valid
189+
unsafe { NonNull::new_unchecked(v as _) }
174190
}
175191
}
176192

177193
impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
178194
unsafe fn new_userref(v: NonNull<T>) -> Self {
179-
NonNull::new_userref(v.as_ptr())
195+
// SAFETY: The caller has guaranteed the pointer is valid
196+
unsafe { NonNull::new_userref(v.as_ptr()) }
180197
}
181198
}
182199

@@ -231,8 +248,9 @@ where
231248
/// * The pointer is null
232249
/// * The pointed-to range is not in user memory
233250
pub unsafe fn from_raw(ptr: *mut T) -> Self {
234-
T::check_ptr(ptr);
235-
User(NonNull::new_userref(ptr))
251+
// SAFETY: the caller must uphold the safety contract for `from_raw`.
252+
unsafe { T::check_ptr(ptr) };
253+
User(unsafe { NonNull::new_userref(ptr) })
236254
}
237255

238256
/// Converts this value into a raw pointer. The value will no longer be
@@ -280,7 +298,9 @@ where
280298
/// * The pointed-to range does not fit in the address space
281299
/// * The pointed-to range is not in user memory
282300
pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
283-
User(NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>())))
301+
User(unsafe {
302+
NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()))
303+
})
284304
}
285305
}
286306

@@ -301,8 +321,9 @@ where
301321
/// * The pointer is null
302322
/// * The pointed-to range is not in user memory
303323
pub unsafe fn from_ptr<'a>(ptr: *const T) -> &'a Self {
304-
T::check_ptr(ptr);
305-
&*(ptr as *const Self)
324+
// SAFETY: The caller must uphold the safety contract for `from_ptr`.
325+
unsafe { T::check_ptr(ptr) };
326+
unsafe { &*(ptr as *const Self) }
306327
}
307328

308329
/// Creates a `&mut UserRef<[T]>` from a raw pointer. See the struct
@@ -318,8 +339,9 @@ where
318339
/// * The pointer is null
319340
/// * The pointed-to range is not in user memory
320341
pub unsafe fn from_mut_ptr<'a>(ptr: *mut T) -> &'a mut Self {
321-
T::check_ptr(ptr);
322-
&mut *(ptr as *mut Self)
342+
// SAFETY: The caller must uphold the safety contract for `from_mut_ptr`.
343+
unsafe { T::check_ptr(ptr) };
344+
unsafe { &mut *(ptr as *mut Self) }
323345
}
324346

325347
/// Copies `val` into user memory.
@@ -394,7 +416,10 @@ where
394416
/// * The pointed-to range does not fit in the address space
395417
/// * The pointed-to range is not in user memory
396418
pub unsafe fn from_raw_parts<'a>(ptr: *const T, len: usize) -> &'a Self {
397-
&*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *const Self)
419+
// SAFETY: The caller must uphold the safety contract for `from_raw_parts`.
420+
unsafe {
421+
&*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *const Self)
422+
}
398423
}
399424

400425
/// Creates a `&mut UserRef<[T]>` from a raw thin pointer and a slice length.
@@ -412,7 +437,10 @@ where
412437
/// * The pointed-to range does not fit in the address space
413438
/// * The pointed-to range is not in user memory
414439
pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut T, len: usize) -> &'a mut Self {
415-
&mut *(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self)
440+
// SAFETY: The caller must uphold the safety contract for `from_raw_parts_mut`.
441+
unsafe {
442+
&mut *(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self)
443+
}
416444
}
417445

418446
/// Obtain a raw pointer to the first element of this user slice.
@@ -437,13 +465,12 @@ where
437465
/// This function panics if the destination doesn't have the same size as
438466
/// the source. This can happen for dynamically-sized types such as slices.
439467
pub fn copy_to_enclave_vec(&self, dest: &mut Vec<T>) {
440-
unsafe {
441-
if let Some(missing) = self.len().checked_sub(dest.capacity()) {
442-
dest.reserve(missing)
443-
}
444-
dest.set_len(self.len());
445-
self.copy_to_enclave(&mut dest[..]);
468+
if let Some(missing) = self.len().checked_sub(dest.capacity()) {
469+
dest.reserve(missing)
446470
}
471+
// SAFETY: We reserve enough space above.
472+
unsafe { dest.set_len(self.len()) };
473+
self.copy_to_enclave(&mut dest[..]);
447474
}
448475

449476
/// Copies the value from user memory into a vector in enclave memory.

library/std/src/sys/sgx/abi/usercalls/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ pub fn connect_stream(addr: &str) -> IoResult<(Fd, String, String)> {
140140
/// Usercall `launch_thread`. See the ABI documentation for more information.
141141
#[unstable(feature = "sgx_platform", issue = "56975")]
142142
pub unsafe fn launch_thread() -> IoResult<()> {
143-
raw::launch_thread().from_sgx_result()
143+
// SAFETY: The caller must uphold the safety contract for `launch_thread`.
144+
unsafe { raw::launch_thread().from_sgx_result() }
144145
}
145146

146147
/// Usercall `exit`. See the ABI documentation for more information.

library/std/src/sys/sgx/abi/usercalls/raw.rs

+35-35
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub unsafe fn do_usercall(
3333
p4: u64,
3434
abort: bool,
3535
) -> (u64, u64) {
36-
let UsercallReturn(a, b) = usercall(nr, p1, p2, abort as _, p3, p4);
36+
let UsercallReturn(a, b) = unsafe { usercall(nr, p1, p2, abort as _, p3, p4) };
3737
(a, b)
3838
}
3939

@@ -175,14 +175,14 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
175175
#[unstable(feature = "sgx_platform", issue = "56975")]
176176
#[inline(always)]
177177
pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3, $n4: $t4) -> $r {
178-
ReturnValue::from_registers(stringify!($f), do_usercall(
179-
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
180-
RegisterArgument::into_register($n1),
181-
RegisterArgument::into_register($n2),
182-
RegisterArgument::into_register($n3),
183-
RegisterArgument::into_register($n4),
184-
return_type_is_abort!($r)
185-
))
178+
ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
179+
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
180+
RegisterArgument::into_register($n1),
181+
RegisterArgument::into_register($n2),
182+
RegisterArgument::into_register($n3),
183+
RegisterArgument::into_register($n4),
184+
return_type_is_abort!($r)
185+
) })
186186
}
187187
);
188188
(def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty, $n3:ident: $t3:ty) -> $r:tt) => (
@@ -191,14 +191,14 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
191191
#[unstable(feature = "sgx_platform", issue = "56975")]
192192
#[inline(always)]
193193
pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3) -> $r {
194-
ReturnValue::from_registers(stringify!($f), do_usercall(
195-
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
196-
RegisterArgument::into_register($n1),
197-
RegisterArgument::into_register($n2),
198-
RegisterArgument::into_register($n3),
199-
0,
200-
return_type_is_abort!($r)
201-
))
194+
ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
195+
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
196+
RegisterArgument::into_register($n1),
197+
RegisterArgument::into_register($n2),
198+
RegisterArgument::into_register($n3),
199+
0,
200+
return_type_is_abort!($r)
201+
) })
202202
}
203203
);
204204
(def fn $f:ident($n1:ident: $t1:ty, $n2:ident: $t2:ty) -> $r:tt) => (
@@ -207,13 +207,13 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
207207
#[unstable(feature = "sgx_platform", issue = "56975")]
208208
#[inline(always)]
209209
pub unsafe fn $f($n1: $t1, $n2: $t2) -> $r {
210-
ReturnValue::from_registers(stringify!($f), do_usercall(
211-
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
212-
RegisterArgument::into_register($n1),
213-
RegisterArgument::into_register($n2),
214-
0,0,
215-
return_type_is_abort!($r)
216-
))
210+
ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
211+
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
212+
RegisterArgument::into_register($n1),
213+
RegisterArgument::into_register($n2),
214+
0,0,
215+
return_type_is_abort!($r)
216+
) })
217217
}
218218
);
219219
(def fn $f:ident($n1:ident: $t1:ty) -> $r:tt) => (
@@ -222,12 +222,12 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
222222
#[unstable(feature = "sgx_platform", issue = "56975")]
223223
#[inline(always)]
224224
pub unsafe fn $f($n1: $t1) -> $r {
225-
ReturnValue::from_registers(stringify!($f), do_usercall(
226-
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
227-
RegisterArgument::into_register($n1),
228-
0,0,0,
229-
return_type_is_abort!($r)
230-
))
225+
ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
226+
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
227+
RegisterArgument::into_register($n1),
228+
0,0,0,
229+
return_type_is_abort!($r)
230+
) })
231231
}
232232
);
233233
(def fn $f:ident() -> $r:tt) => (
@@ -236,11 +236,11 @@ macro_rules! enclave_usercalls_internal_define_usercalls {
236236
#[unstable(feature = "sgx_platform", issue = "56975")]
237237
#[inline(always)]
238238
pub unsafe fn $f() -> $r {
239-
ReturnValue::from_registers(stringify!($f), do_usercall(
240-
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
241-
0,0,0,0,
242-
return_type_is_abort!($r)
243-
))
239+
ReturnValue::from_registers(stringify!($f), unsafe { do_usercall(
240+
rtunwrap!(Some, NonZeroU64::new(Usercalls::$f as Register)),
241+
0,0,0,0,
242+
return_type_is_abort!($r)
243+
) })
244244
}
245245
);
246246
(def fn $f:ident($($n:ident: $t:ty),*)) => (

library/std/src/sys/sgx/alloc.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ use super::waitqueue::SpinMutex;
44

55
// Using a SpinMutex because we never want to exit the enclave waiting for the
66
// allocator.
7+
//
8+
// The current allocator here is the `dlmalloc` crate which we've got included
9+
// in the rust-lang/rust repository as a submodule. The crate is a port of
10+
// dlmalloc.c from C to Rust.
711
#[cfg_attr(test, linkage = "available_externally")]
812
#[export_name = "_ZN16__rust_internals3std3sys3sgx5alloc8DLMALLOCE"]
913
static DLMALLOC: SpinMutex<dlmalloc::Dlmalloc> = SpinMutex::new(dlmalloc::DLMALLOC_INIT);
@@ -12,22 +16,26 @@ static DLMALLOC: SpinMutex<dlmalloc::Dlmalloc> = SpinMutex::new(dlmalloc::DLMALL
1216
unsafe impl GlobalAlloc for System {
1317
#[inline]
1418
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
15-
DLMALLOC.lock().malloc(layout.size(), layout.align())
19+
// SAFETY: the caller must uphold the safety contract for `malloc`
20+
unsafe { DLMALLOC.lock().malloc(layout.size(), layout.align()) }
1621
}
1722

1823
#[inline]
1924
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
20-
DLMALLOC.lock().calloc(layout.size(), layout.align())
25+
// SAFETY: the caller must uphold the safety contract for `malloc`
26+
unsafe { DLMALLOC.lock().calloc(layout.size(), layout.align()) }
2127
}
2228

2329
#[inline]
2430
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
25-
DLMALLOC.lock().free(ptr, layout.size(), layout.align())
31+
// SAFETY: the caller must uphold the safety contract for `malloc`
32+
unsafe { DLMALLOC.lock().free(ptr, layout.size(), layout.align()) }
2633
}
2734

2835
#[inline]
2936
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
30-
DLMALLOC.lock().realloc(ptr, layout.size(), layout.align(), new_size)
37+
// SAFETY: the caller must uphold the safety contract for `malloc`
38+
unsafe { DLMALLOC.lock().realloc(ptr, layout.size(), layout.align(), new_size) }
3139
}
3240
}
3341

@@ -36,11 +44,11 @@ unsafe impl GlobalAlloc for System {
3644
#[cfg(not(test))]
3745
#[no_mangle]
3846
pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 {
39-
crate::alloc::alloc(Layout::from_size_align_unchecked(size, align))
47+
unsafe { crate::alloc::alloc(Layout::from_size_align_unchecked(size, align)) }
4048
}
4149

4250
#[cfg(not(test))]
4351
#[no_mangle]
4452
pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) {
45-
crate::alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align))
53+
unsafe { crate::alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) }
4654
}

library/std/src/sys/sgx/args.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type ArgsStore = Vec<OsString>;
1313
#[cfg_attr(test, allow(dead_code))]
1414
pub unsafe fn init(argc: isize, argv: *const *const u8) {
1515
if argc != 0 {
16-
let args = alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _);
16+
let args = unsafe { alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _) };
1717
let args = args
1818
.iter()
1919
.map(|a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }))

library/std/src/sys/sgx/condvar.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ impl Condvar {
2727

2828
pub unsafe fn wait(&self, mutex: &Mutex) {
2929
let guard = self.inner.lock();
30-
WaitQueue::wait(guard, || mutex.unlock());
31-
mutex.lock()
30+
WaitQueue::wait(guard, || unsafe { mutex.unlock() });
31+
unsafe { mutex.lock() }
3232
}
3333

3434
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
35-
let success = WaitQueue::wait_timeout(&self.inner, dur, || mutex.unlock());
36-
mutex.lock();
35+
let success = WaitQueue::wait_timeout(&self.inner, dur, || unsafe { mutex.unlock() });
36+
unsafe { mutex.lock() };
3737
success
3838
}
3939

0 commit comments

Comments
 (0)