From b0dde81c75255abddfb6acff9f3a4b14ba804346 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jeremy@system76.com> Date: Sun, 7 Jun 2020 14:00:48 -0600 Subject: [PATCH] Handle missing paths in load_library search without using access --- src/ld_so/linker.rs | 54 +++++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index b70a46fae..a835a2e91 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -21,7 +21,7 @@ use crate::{ c_str::CString, fs::File, header::{fcntl, sys_mman, unistd}, - io::Read, + io::{self, Read}, platform::types::c_void, }; @@ -94,41 +94,54 @@ impl Linker { } pub fn load(&mut self, name: &str, path: &str) -> Result<()> { - self.dep_tree = self.load_recursive(name, path)?; + self.dep_tree = self.load_recursive(name, path)? + .ok_or(Error::Malformed(format!( + "failed to find '{}'", + path + )))?; if self.verbose { println!("Dep tree: {:#?}", self.dep_tree); } return Ok(()); } - fn load_recursive(&mut self, name: &str, path: &str) -> Result<DepTree> { + fn load_recursive(&mut self, name: &str, path: &str) -> Result<Option<DepTree>> { if self.verbose { println!("load {}: {}", name, path); } - if self.cir_dep.contains(name) { - return Err(Error::Malformed(format!( - "Circular dependency: {} is a dependency of itself", - name - ))); - } - let mut deps = DepTree::new(name.to_string()); - let mut data = Vec::new(); - self.cir_dep.insert(name.to_string()); let path_c = CString::new(path) .map_err(|err| Error::Malformed(format!("invalid path '{}': {}", path, err)))?; + let mut data = Vec::new(); { let flags = fcntl::O_RDONLY | fcntl::O_CLOEXEC; - let mut file = File::open(&path_c, flags) - .map_err(|err| Error::Malformed(format!("failed to open '{}': {}", path, err)))?; + let mut file = match File::open(&path_c, flags) { + Ok(ok) => ok, + Err(err) => match err.kind() { + io::ErrorKind::NotFound => return Ok(None), + _ => return Err(Error::Malformed(format!("failed to open '{}': {}", path, err))) + } + }; file.read_to_end(&mut data) .map_err(|err| Error::Malformed(format!("failed to read '{}': {}", path, err)))?; } + + if self.cir_dep.contains(name) { + return Err(Error::Malformed(format!( + "Circular dependency: {} is a dependency of itself", + name + ))); + } + self.cir_dep.insert(name.to_string()); + + let mut deps = DepTree::new(name.to_string()); deps.deps = self.load_data(name, data.into_boxed_slice())?; + self.cir_dep.remove(name); - Ok(deps) + + Ok(Some(deps)) } pub fn load_data(&mut self, name: &str, data: Box<[u8]>) -> Result<Vec<DepTree>> { @@ -151,7 +164,12 @@ impl Linker { // It should be previously resolved so we don't need to worry about it Ok(None) } else if name.contains('/') { - Ok(Some(self.load_recursive(name, name)?)) + Ok(Some(self.load_recursive(name, name)? + .ok_or(Error::Malformed(format!( + "failed to find '{}'", + name + )))? + )) } else { let library_path = self.library_path.clone(); for part in library_path.split(PATH_SEP) { @@ -163,7 +181,9 @@ impl Linker { if self.verbose { println!("check {}", path); } - return Ok(Some(self.load_recursive(name, &path)?)); + if let Some(deps) = self.load_recursive(name, &path)? { + return Ok(Some(deps)); + } } Err(Error::Malformed(format!("failed to locate '{}'", name))) -- GitLab