diff --git a/src/ld_so/dso.rs b/src/ld_so/dso.rs index e29d327033..64b0ef7298 100644 --- a/src/ld_so/dso.rs +++ b/src/ld_so/dso.rs @@ -30,6 +30,7 @@ use core::{ mem::{offset_of, size_of}, ptr::{self, NonNull}, slice, + sync::atomic::{AtomicBool, Ordering}, }; pub const CHAR_BITS: usize = size_of::() * 8; @@ -334,6 +335,9 @@ pub struct DSO { pub scope: spin::Once, /// Position Independent Executable. pub pie: bool, + + /// Whether this DSO *and* its dependencies have been successfully loaded. + is_ready: AtomicBool, } impl DSO { @@ -380,11 +384,17 @@ impl DSO { pie: is_pie_enabled(&elf), dynamic, scope: spin::Once::new(), + is_ready: AtomicBool::new(false), }; Ok((dso, tcb_master, elf.elf_program_headers().to_vec())) } + #[inline] + pub fn mark_ready(&self) { + self.is_ready.store(true, Ordering::SeqCst); + } + #[inline] pub fn scope(&self) -> &Scope { self.scope.get().expect("scope not initialized") @@ -1120,7 +1130,11 @@ impl DSO { impl Drop for DSO { fn drop(&mut self) { - self.run_fini(); + if self.is_ready.load(Ordering::SeqCst) { + // `run_fini` should not be called if we are being prematurely + // dropped (e.g. failed to satisfy dependencies). + self.run_fini(); + } unsafe { Sys::munmap(self.mmap.as_ptr() as *mut c_void, self.mmap.len()).unwrap() }; } } diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index 073966ef1d..52b79dc5f1 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -715,6 +715,7 @@ impl Linker { } for obj in new_objects.into_iter() { + obj.mark_ready(); self.run_init(&obj); self.register_object(obj); }