From 6497d71d2fb325dc052ed41192b52723e763bdb6 Mon Sep 17 00:00:00 2001 From: Mateusz Tabaka Date: Wed, 30 Dec 2020 18:14:53 +0100 Subject: [PATCH] Fix dlsym of TLS variables --- src/ld_so/dso.rs | 2 ++ src/ld_so/linker.rs | 29 +++++++++++++++++++++++++---- src/ld_so/tcb.rs | 8 ++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/ld_so/dso.rs b/src/ld_so/dso.rs index 3f053d091e..f8e72d7ae6 100644 --- a/src/ld_so/dso.rs +++ b/src/ld_so/dso.rs @@ -358,12 +358,14 @@ impl DSO { base: mmap.as_ptr() as usize, value: sym.st_value as usize, size: sym.st_size as usize, + sym_type: sym::st_type(sym.st_info), } } else { Symbol { base: 0, value: sym.st_value as usize, size: sym.st_size as usize, + sym_type: sym::st_type(sym.st_info), } }; } else { diff --git a/src/ld_so/linker.rs b/src/ld_so/linker.rs index 21d35b1804..f90bdb41ef 100644 --- a/src/ld_so/linker.rs +++ b/src/ld_so/linker.rs @@ -6,14 +6,18 @@ use alloc::{ }; use core::{cell::RefCell, mem::transmute, ptr}; use goblin::{ - elf::{program_header, reloc, Elf}, + elf::{program_header, reloc, sym::STT_TLS, Elf}, error::{Error, Result}, }; use crate::{ c_str::CString, fs::File, - header::{fcntl, sys_mman, unistd::F_OK}, + header::{ + dl_tls::{__tls_get_addr, dl_tls_index}, + fcntl, sys_mman, + unistd::F_OK, + }, io::Read, platform::types::c_void, }; @@ -32,6 +36,7 @@ pub struct Symbol { pub value: usize, pub base: usize, pub size: usize, + pub sym_type: u8, } impl Symbol { @@ -91,8 +96,24 @@ impl Linker { pub fn get_sym(&self, lib_id: usize, name: &str) -> Option<*mut c_void> { match self.objects.get(&lib_id) { - Some(obj) => obj.get_sym(name).map(|s| s.as_ptr()), - _ => None, + Some(obj) => { + return obj.get_sym(name).map(|s| { + if s.sym_type != STT_TLS { + s.as_ptr() + } else { + unsafe { + let mut tls_index = dl_tls_index { + ti_module: obj.tls_module_id as u64, + ti_offset: s.value as u64, + }; + __tls_get_addr(&mut tls_index) + } + } + }); + } + _ => { + return None; + } } } diff --git a/src/ld_so/tcb.rs b/src/ld_so/tcb.rs index 0ff9e557d3..152486aa50 100644 --- a/src/ld_so/tcb.rs +++ b/src/ld_so/tcb.rs @@ -40,7 +40,7 @@ pub struct Tcb { /// Size of the masters list in bytes (multiple of mem::size_of::()) pub masters_len: usize, /// Index of last copied Master - pub last_master_copied: usize, + pub num_copied_masters: usize, /// Pointer to dynamic linker pub linker_ptr: *const Mutex, /// pointer to rust memory allocator structure @@ -63,7 +63,7 @@ impl Tcb { tcb_len: tcb_page.len(), masters_ptr: ptr::null_mut(), masters_len: 0, - last_master_copied: 0, + num_copied_masters: 0, linker_ptr: ptr::null(), mspace: 0, }, @@ -114,7 +114,7 @@ impl Tcb { if let Some(masters) = self.masters() { for (i, master) in masters .iter() - .skip(self.last_master_copied) + .skip(self.num_copied_masters) .filter(|m| m.len > 0) .enumerate() { @@ -135,7 +135,7 @@ impl Tcb { return Err(Error::Malformed(format!("failed to copy tls master {}", i))); } } - self.last_master_copied = masters.len(); + self.num_copied_masters = masters.len(); } }