diff options
| author | ShE3py <52315535+she3py@users.noreply.github.com> | 2023-08-18 16:04:53 +0200 |
|---|---|---|
| committer | ShE3py <52315535+she3py@users.noreply.github.com> | 2023-08-18 16:04:53 +0200 |
| commit | 83c713bff022acabc4dab30510f35122e29d0f53 (patch) | |
| tree | f8d247c25f4e8e1b495ec527355462fda18c79e3 /library/std/src/sys/unix | |
| parent | 0f7f6b70617fbcda9f73755fa9b560bfb0a588eb (diff) | |
| download | rust-83c713bff022acabc4dab30510f35122e29d0f53.tar.gz rust-83c713bff022acabc4dab30510f35122e29d0f53.zip | |
Fix UB in `std::sys::os::getenv()`
Diffstat (limited to 'library/std/src/sys/unix')
| -rw-r--r-- | library/std/src/sys/unix/os.rs | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 215f63d04f7..57e1a36dace 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -594,16 +594,21 @@ pub fn env() -> Env { pub fn getenv(k: &OsStr) -> Option<OsString> { // environment variables with a nul byte can't be set, so their value is // always None as well - let s = run_with_cstr(k.as_bytes(), |k| { + run_with_cstr(k.as_bytes(), |k| { let _guard = env_read_lock(); - Ok(unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char) + let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char; + + if v.is_null() { + Ok(None) + } else { + // SAFETY: `v` cannot be mutated while executing this line since we've a read lock + let bytes = unsafe { CStr::from_ptr(v) }.to_bytes().to_vec(); + + Ok(Some(OsStringExt::from_vec(bytes))) + } }) - .ok()?; - if s.is_null() { - None - } else { - Some(OsStringExt::from_vec(unsafe { CStr::from_ptr(s) }.to_bytes().to_vec())) - } + .ok() + .flatten() } pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { |
