Fix the avoid accessing errno issue from ld_so for real this time

This patch implements access function for both redox and linux and makes
sure that neither access errno variable
This commit is contained in:
oddcoder
2020-06-13 19:50:08 +02:00
parent d5b63a85a4
commit 81da1bb1a3
3 changed files with 57 additions and 9 deletions
+53
View File
@@ -0,0 +1,53 @@
// Wrapper over the access syscall that doesn't touch errno variable,
// Do not use outside of ld_so
use crate::{c_str::CStr, platform::types::*};
#[cfg(target_os = "redox")]
use crate::header::unistd::{F_OK, R_OK, W_OK, X_OK};
#[cfg(target_os = "linux")]
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
}
// Wrapper over the systemcall, Do not use outside of ld_so
#[cfg(target_os = "redox")]
pub unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
let path = CStr::from_ptr(path).to_bytes();
let fd = match syscall::open(path, syscall::O_CLOEXEC) {
Ok(fd) => fd,
_ => return -1,
};
if mode == F_OK {
return 0;
}
let mut stat = syscall::Stat::default();
if syscall::fstat(fd, &mut stat).is_err() {
return -1;
}
let uid = match syscall::getuid() {
Ok(uid) => uid,
Err(_) => return -1,
};
let gid = match syscall::getgid() {
Ok(gid) => gid,
Err(_) => return -1,
};
let perms = if stat.st_uid as usize == uid {
stat.st_mode >> (3 * 2 & 0o7)
} else if stat.st_gid as usize == gid {
stat.st_mode >> (3 * 1 & 0o7)
} else {
stat.st_mode & 0o7
};
if (mode & R_OK == R_OK && perms & 0o4 != 0o4)
|| (mode & W_OK == W_OK && perms & 0o2 != 0o2)
|| (mode & X_OK == X_OK && perms & 0o1 != 0o1)
{
return -1;
}
0
}
+1 -2
View File
@@ -26,12 +26,11 @@ use crate::{
};
use super::{
access,
access::access,
debug::{RTLDDebug, RTLDState, _dl_debug_state, _r_debug},
tcb::{Master, Tcb},
PAGE_SIZE,
};
#[cfg(target_os = "redox")]
const PATH_SEP: char = ';';
+3 -7
View File
@@ -1,13 +1,15 @@
use goblin::elf::program_header::{self, program_header32, program_header64, ProgramHeader};
use self::tcb::{Master, Tcb};
use crate::{c_str::CStr, platform::types::*, start::Stack};
use crate::start::Stack;
pub const PAGE_SIZE: usize = 4096;
mod access;
pub mod debug;
pub mod linker;
pub mod start;
pub mod tcb;
pub fn static_init(sp: &'static Stack) {
let mut phdr_opt = None;
let mut phent_opt = None;
@@ -79,12 +81,6 @@ 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;