Skip to content

Commit f3a33ce

Browse files
committed
SGX: Use OnceLock for env::Args and LazyLock for env::Vars
Fixes fuzzy provenance casts with `AtomicUsize`.
1 parent d6c1e45 commit f3a33ce

File tree

2 files changed

+18
-43
lines changed

2 files changed

+18
-43
lines changed

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

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
#![allow(fuzzy_provenance_casts)] // FIXME: this module systematically confuses pointers and integers
2-
31
use crate::ffi::OsString;
4-
use crate::sync::atomic::{AtomicUsize, Ordering};
2+
use crate::sync::OnceLock;
53
use crate::sys::os_str::Buf;
64
use crate::sys::pal::abi::usercalls::alloc;
75
use crate::sys::pal::abi::usercalls::raw::ByteBuffer;
@@ -11,23 +9,23 @@ use crate::{fmt, slice};
119
// Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests
1210
#[cfg_attr(test, linkage = "available_externally")]
1311
#[unsafe(export_name = "_ZN16__rust_internals3std3sys3sgx4args4ARGSE")]
14-
static ARGS: AtomicUsize = AtomicUsize::new(0);
12+
static ARGS: OnceLock<ArgsStore> = OnceLock::new();
1513
type ArgsStore = Vec<OsString>;
1614

1715
#[cfg_attr(test, allow(dead_code))]
1816
pub unsafe fn init(argc: isize, argv: *const *const u8) {
1917
if argc != 0 {
20-
let args = unsafe { alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _) };
21-
let args = args
22-
.iter()
23-
.map(|a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }))
24-
.collect::<ArgsStore>();
25-
ARGS.store(Box::into_raw(Box::new(args)) as _, Ordering::Relaxed);
18+
ARGS.get_or_init(|| {
19+
let args = unsafe { alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _) };
20+
args.iter()
21+
.map(|a| OsString::from_inner(Buf { inner: a.copy_user_buffer() }))
22+
.collect::<ArgsStore>()
23+
});
2624
}
2725
}
2826

2927
pub fn args() -> Args {
30-
let args = unsafe { (ARGS.load(Ordering::Relaxed) as *const ArgsStore).as_ref() };
28+
let args = ARGS.get();
3129
if let Some(args) = args { Args(args.iter()) } else { Args([].iter()) }
3230
}
3331

library/std/src/sys/pal/sgx/os.rs

+9-32
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
#![forbid(fuzzy_provenance_casts)]
2+
13
use fortanix_sgx_abi::{Error, RESULT_SUCCESS};
24

35
use crate::collections::HashMap;
46
use crate::error::Error as StdError;
57
use crate::ffi::{OsStr, OsString};
68
use crate::marker::PhantomData;
79
use crate::path::{self, PathBuf};
8-
use crate::sync::atomic::{AtomicUsize, Ordering};
9-
use crate::sync::{Mutex, Once};
10+
use crate::sync::{LazyLock, Mutex};
1011
use crate::sys::{decode_error_kind, sgx_ineffective, unsupported};
1112
use crate::{fmt, io, str, vec};
1213

@@ -76,24 +77,9 @@ pub fn current_exe() -> io::Result<PathBuf> {
7677
// Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests
7778
#[cfg_attr(test, linkage = "available_externally")]
7879
#[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os3ENVE")]
79-
static ENV: AtomicUsize = AtomicUsize::new(0);
80-
// Specifying linkage/symbol name is solely to ensure a single instance between this crate and its unit tests
81-
#[cfg_attr(test, linkage = "available_externally")]
82-
#[unsafe(export_name = "_ZN16__rust_internals3std3sys3pal3sgx2os8ENV_INITE")]
83-
static ENV_INIT: Once = Once::new();
80+
static ENV: LazyLock<EnvStore> = LazyLock::new(|| EnvStore::default());
8481
type EnvStore = Mutex<HashMap<OsString, OsString>>;
8582

86-
fn get_env_store() -> Option<&'static EnvStore> {
87-
unsafe { (ENV.load(Ordering::Relaxed) as *const EnvStore).as_ref() }
88-
}
89-
90-
fn create_env_store() -> &'static EnvStore {
91-
ENV_INIT.call_once(|| {
92-
ENV.store(Box::into_raw(Box::new(EnvStore::default())) as _, Ordering::Relaxed)
93-
});
94-
unsafe { &*(ENV.load(Ordering::Relaxed) as *const EnvStore) }
95-
}
96-
9783
pub struct Env {
9884
iter: vec::IntoIter<(OsString, OsString)>,
9985
}
@@ -140,31 +126,22 @@ impl Iterator for Env {
140126
}
141127

142128
pub fn env() -> Env {
143-
let clone_to_vec = |map: &HashMap<OsString, OsString>| -> Vec<_> {
144-
map.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
145-
};
146-
147-
let iter = get_env_store()
148-
.map(|env| clone_to_vec(&env.lock().unwrap()))
149-
.unwrap_or_default()
150-
.into_iter();
151-
Env { iter }
129+
let env = ENV.lock().unwrap().iter().map(|(k, v)| (k.clone(), v.clone())).collect::<Vec<_>>();
130+
Env { iter: env.into_iter() }
152131
}
153132

154133
pub fn getenv(k: &OsStr) -> Option<OsString> {
155-
get_env_store().and_then(|s| s.lock().unwrap().get(k).cloned())
134+
ENV.lock().unwrap().get(k).cloned()
156135
}
157136

158137
pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
159138
let (k, v) = (k.to_owned(), v.to_owned());
160-
create_env_store().lock().unwrap().insert(k, v);
139+
ENV.lock().unwrap().insert(k, v);
161140
Ok(())
162141
}
163142

164143
pub unsafe fn unsetenv(k: &OsStr) -> io::Result<()> {
165-
if let Some(env) = get_env_store() {
166-
env.lock().unwrap().remove(k);
167-
}
144+
ENV.lock().unwrap().remove(k);
168145
Ok(())
169146
}
170147

0 commit comments

Comments
 (0)