fix(linker): deref uninit TCB
The bug is described for `x86_64` and Linux but is the same for other architectures and on Redox. `Tcb::current()` is used to retrieve the current TCB, which is done by by reading `fs:[0x10]`. The TCB layout describes that at offset `0x10`, there is `tcb_ptr: *mut GenericTcb<...>`, which is nothing more but a pointer to itself. This is fine as otherwise a system call would be required to get the TCB (`arch_prctl(ARCH_GET_FS)` on Linux). However, this is problematic as the function may be called when the FS base is not set, and in that case the expected output of the function should be [`None`], but we don't currently handle that. To fix this, any code paths that maybe call this function on an uninitialized TCB are be switched to call `current_slow()`. Which just uses `arch_prctl(ARCH_GET_FS)` to get the FS base and check if it's non-zero. Signed-off-by: Anhad Singh <andypython@protonmail.com>
This commit is contained in:
@@ -47,7 +47,7 @@ pub unsafe extern "C" fn dlopen(cfilename: *const c_char, flags: c_int) -> *mut
|
||||
))
|
||||
};
|
||||
|
||||
let tcb = match Tcb::current() {
|
||||
let tcb = match Tcb::current_slow() {
|
||||
Some(tcb) => tcb,
|
||||
None => {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
@@ -83,7 +83,7 @@ pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *m
|
||||
|
||||
let symbol_str = str::from_utf8_unchecked(CStr::from_ptr(symbol).to_bytes());
|
||||
|
||||
let tcb = match Tcb::current() {
|
||||
let tcb = match Tcb::current_slow() {
|
||||
Some(tcb) => tcb,
|
||||
None => {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
@@ -110,7 +110,7 @@ pub unsafe extern "C" fn dlsym(handle: *mut c_void, symbol: *const c_char) -> *m
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dlclose(handle: *mut c_void) -> c_int {
|
||||
let tcb = match Tcb::current() {
|
||||
let tcb = match Tcb::current_slow() {
|
||||
Some(tcb) => tcb,
|
||||
None => {
|
||||
ERROR.store(ERROR_NOT_SUPPORTED.as_ptr() as usize, Ordering::SeqCst);
|
||||
|
||||
Reference in New Issue
Block a user