From 1b10c3d24628441a1357f6079824d543a12e4e53 Mon Sep 17 00:00:00 2001 From: oddcoder Date: Mon, 1 Jun 2020 11:41:19 +0200 Subject: [PATCH 1/2] Prioterize search path instead of overwriting it. Current LD_LIBRARY_PATH implementation overwrites the original search path, which is not the best idea, instead this patch would check LD_LIBRARY_PATH first and if it didn't find the libraries it is looking for, then it will search the original search path --- src/ld_so/start.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ld_so/start.rs b/src/ld_so/start.rs index 7b433faa4a..92e83a3bd1 100644 --- a/src/ld_so/start.rs +++ b/src/ld_so/start.rs @@ -138,8 +138,8 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) -> // Some variables that will be overridden by environment and auxiliary vectors let library_path = match envs.get("LD_LIBRARY_PATH") { - Some(lib_path) => lib_path, - None => "/lib", + Some(lib_path) => lib_path.to_owned() + ":/lib", + None => "/lib".to_owned(), }; let path = if is_manual { @@ -178,7 +178,7 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) -> } pr }; - let mut linker = Linker::new(library_path, false); + let mut linker = Linker::new(&library_path, false); match linker.load(&path, &path) { Ok(()) => (), Err(err) => { From 3aacc160a14b3c65b4c6feeb456a495a7308a27d Mon Sep 17 00:00:00 2001 From: oddcoder Date: Mon, 1 Jun 2020 11:49:38 +0200 Subject: [PATCH 2/2] Remove dependency on errno in ld.so During early parts of ld.so, errno and other thread local variables are not yet initialized so we cannot use function (such as unistd::access) that depends on such thread local variables (errno). For this reason this patch creates small wrapper around the syscall that doesn't not touch the errno --- src/ld_so/linker.rs | 5 ++++- src/ld_so/mod.rs | 13 +++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index 4aea9b4100..503fe1b7e3 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -29,6 +29,7 @@ use super::{ debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug}, tcb::{Master, Tcb}, PAGE_SIZE, + access, }; #[cfg(target_os = "redox")] @@ -169,7 +170,9 @@ impl Linker { })?; // TODO: Use R_OK | X_OK - unistd::access(path_c.as_ptr(), unistd::F_OK) == 0 + // We cannot use unix stdlib because errno is thead local variable + // and fs:[0] is not set yet. + access(path_c.as_ptr(), unistd::F_OK) == 0 }; if access { diff --git a/src/ld_so/mod.rs b/src/ld_so/mod.rs index 1d06541ac1..46a7a271a9 100644 --- a/src/ld_so/mod.rs +++ b/src/ld_so/mod.rs @@ -1,8 +1,11 @@ use goblin::elf::program_header::{self, program_header32, program_header64, ProgramHeader}; use self::tcb::{Master, Tcb}; -use crate::start::Stack; - +use crate::{ +start::Stack, +c_str::CStr, +platform::types::* +}; pub const PAGE_SIZE: usize = 4096; pub mod debug; @@ -80,6 +83,12 @@ pub fn static_init(sp: &'static Stack) { } } +// Wrapper over the systemcall, Do not use outside of ld_so +pub unsafe fn access(path: *const c_char, mode: c_int) -> c_int { + let path = CStr::from_ptr(path); + syscall!(ACCESS, (path).as_ptr(), mode) as c_int +} + #[cfg(target_os = "linux")] pub unsafe fn init(sp: &'static Stack) { let mut tp = 0usize;