From c3ae8022bad7e1aca96524ff47558bd5f5ae9cde Mon Sep 17 00:00:00 2001
From: no name <no@mail>
Date: Tue, 9 Jun 2020 11:18:28 +0000
Subject: [PATCH] Revert "Handle missing paths in load_library search without
 using access"

This reverts commit b0dde81c75255abddfb6acff9f3a4b14ba804346.

The main issue was not with "access" being used, it was with errno being
accessed. This patch accesses errno as well

LD_LIBRARY_PATH="/folder/with/no/libc" ./a.out

gives segfault with the following stack trace

0x00000000004d1cae in relibc::platform::sys::e (sys=18446744073709551614) at src/platform/linux/mod.rs:54
 54                  errno = -(sys as isize) as c_int;
(gdb) bt
 #0  0x00000000004d1cae in relibc::platform::sys::e (sys=18446744073709551614) at src/platform/linux/mod.rs:54
 #1  0x00000000004d361e in <relibc::platform::sys::Sys as relibc::platform::pal::Pal>::open (path=0x5555555634c0, oflag=524288, mode=0) at src/platform/linux/mod.rs:330
 #2  0x000000000049a2ad in relibc::fs::File::open (path=0x5555555634c0, oflag=524288) at src/fs.rs:28
 #3  0x0000000000482b49 in relibc::ld_so::linker::Linker::load_recursive (self=0x7fffffffdd30, name=..., path=...) at src/ld_so/linker.rs:119
 #4  0x0000000000484963 in relibc::ld_so::linker::Linker::load_library (self=0x7fffffffdd30, name=...) at src/ld_so/linker.rs:184
 #5  0x0000000000483b53 in relibc::ld_so::linker::Linker::load_data (self=0x7fffffffdd30, name=..., data=...) at src/ld_so/linker.rs:152
 #6  0x00000000004831fe in relibc::ld_so::linker::Linker::load_recursive (self=0x7fffffffdd30, name=..., path=...) at src/ld_so/linker.rs:140
 #7  0x000000000048228a in relibc::ld_so::linker::Linker::load (self=0x7fffffffdd30, name=..., path=...) at src/ld_so/linker.rs:97
 #8  0x0000000000414a3b in relibc_ld_so_start (sp=0x7fffffffe310, ld_entry=4198896) at src/ld_so/start.rs:182
 #9  0x0000000000401209 in _start () at src/ld_so/src/lib.rs:10
 #10 0x0000000000000001 in ?? ()
 #11 0x00007fffffffe592 in ?? ()
 #12 0x0000000000000000 in ?? ()
---
 src/ld_so/linker.rs | 54 ++++++++++++++-------------------------------
 1 file changed, 17 insertions(+), 37 deletions(-)

diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs
index a835a2e91..b70a46fae 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::{self, Read},
+    io::Read,
     platform::types::c_void,
 };
 
@@ -94,54 +94,41 @@ impl Linker {
     }
 
     pub fn load(&mut self, name: &str, path: &str) -> Result<()> {
-        self.dep_tree = self.load_recursive(name, path)?
-            .ok_or(Error::Malformed(format!(
-                "failed to find '{}'",
-                path
-            )))?;
+        self.dep_tree = self.load_recursive(name, path)?;
         if self.verbose {
             println!("Dep tree: {:#?}", self.dep_tree);
         }
         return Ok(());
     }
 
-    fn load_recursive(&mut self, name: &str, path: &str) -> Result<Option<DepTree>> {
+    fn load_recursive(&mut self, name: &str, path: &str) -> Result<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 = 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)))
-                }
-            };
+            let mut file = File::open(&path_c, flags)
+                .map_err(|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(Some(deps))
+        Ok(deps)
     }
 
     pub fn load_data(&mut self, name: &str, data: Box<[u8]>) -> Result<Vec<DepTree>> {
@@ -164,12 +151,7 @@ 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_or(Error::Malformed(format!(
-                    "failed to find '{}'",
-                    name
-                )))?
-            ))
+            Ok(Some(self.load_recursive(name, name)?))
         } else {
             let library_path = self.library_path.clone();
             for part in library_path.split(PATH_SEP) {
@@ -181,9 +163,7 @@ impl Linker {
                 if self.verbose {
                     println!("check {}", path);
                 }
-                if let Some(deps) = self.load_recursive(name, &path)? {
-                    return Ok(Some(deps));
-                }
+                return Ok(Some(self.load_recursive(name, &path)?));
             }
 
             Err(Error::Malformed(format!("failed to locate '{}'", name)))
-- 
GitLab