# Everything about CVE-2020-5499
# The Story
CVE-2020-5499 reported an enclave ID racing problem. We received the report on Nov 1st, 2019 and fixed it on Nov 5th, 2019 with commit f29f4e71896589908cd4b43ed70a623a81eda0e5.
# Analysis and Fix
The global data "enclave ID" was designed to hold the eid of the enclave
instance, and to be used for later provided thread::spawn
feature. In v1.0.8,
we didn't have thread::spawn
. So the data racing is true, but it can hardly
harm the enclave.
To be more clear, let's look at the patch:
diff --git a/sgx_tstd/src/rt.rs b/sgx_tstd/src/rt.rs
index fcfd0a42..3f738a53 100644
--- a/sgx_tstd/src/rt.rs
+++ b/sgx_tstd/src/rt.rs
@@ -36,6 +36,9 @@ use core::str;
pub use crate::panicking::{begin_panic, begin_panic_fmt, update_panic_count};
pub use crate::sys_common::at_exit;
use crate::sys_common::cleanup;
+use crate::sync::Once;
+
+static INIT: Once = Once::new();
#[no_mangle]
pub extern "C" fn t_global_exit_ecall() {
@@ -43,13 +46,14 @@ pub extern "C" fn t_global_exit_ecall() {
#[no_mangle]
pub extern "C" fn t_global_init_ecall(id: u64, path: * const u8, len: usize) {
-
- enclave::set_enclave_id(id as sgx_enclave_id_t);
- let s = unsafe {
- let str_slice = slice::from_raw_parts(path, len);
- str::from_utf8_unchecked(str_slice)
- };
- enclave::set_enclave_path(s);
+ INIT.call_once(|| {
+ enclave::set_enclave_id(id as sgx_enclave_id_t);
+ let s = unsafe {
+ let str_slice = slice::from_raw_parts(path, len);
+ str::from_utf8_unchecked(str_slice)
+ };
+ enclave::set_enclave_path(s);
+ });
}
global_dtors_object! {
Basically, the initiation here should be an atomic operation. To be more safe,
we marked it as Once
, which means that it can only be triggered once.
Overall, we think the threat is subtle. One of the necessary condition is that
the enclave should be started with an undocumented feature of urts:
global_init
. Also the enclave should depend on enclave ID on critical paths.
It's really rare.