From 144ac70b12e888c48c4d923c6aeb21b813d13ff8 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 23 Jun 2019 20:21:22 -0600 Subject: [PATCH] Allow access to other thread's TLS with pointers --- src/consts.rs | 2 ++ src/syscall/process.rs | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/consts.rs b/src/consts.rs index d927ba5..8f59b47 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -61,6 +61,8 @@ /// Offset to user TLS pub const USER_TLS_OFFSET: usize = USER_SIGSTACK_OFFSET + PML4_SIZE; pub const USER_TLS_PML4: usize = (USER_TLS_OFFSET & PML4_MASK)/PML4_SIZE; + // Maximum TLS allocated to each PID, should be approximately 8 MB + pub const USER_TLS_SIZE: usize = PML4_SIZE / 65536; /// Offset to user temporary image (used when cloning) pub const USER_TMP_OFFSET: usize = USER_TLS_OFFSET + PML4_SIZE; diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 1569b02..5946c01 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -529,12 +529,25 @@ pub fn clone(flags: usize, stack_base: usize) -> Result { // Setup user TLS if let Some(mut tls) = tls_option { - tls.mem.move_to(VirtualAddress::new(crate::USER_TLS_OFFSET), &mut new_table, &mut temporary_page); + // Copy TLS mapping + { + let frame = active_table.p4()[crate::USER_TLS_PML4].pointed_frame().expect("user tls not mapped"); + let flags = active_table.p4()[crate::USER_TLS_PML4].flags(); + active_table.with(&mut new_table, &mut temporary_page, |mapper| { + mapper.p4_mut()[crate::USER_TLS_PML4].set(frame, flags); + }); + } + + // TODO: Make sure size is not greater than USER_TLS_SIZE + let tls_addr = crate::USER_TLS_OFFSET + context.id.into() * crate::USER_TLS_SIZE; + println!("{}: Copy TLS: address 0x{:x}, size 0x{:x}", context.id.into(), tls_addr, tls.mem.size()); + tls.mem.move_to(VirtualAddress::new(tls_addr), &mut new_table, &mut temporary_page); unsafe { *(tcb_addr as *mut usize) = tls.mem.start_address().get() + tls.mem.size(); } context.tls = Some(tls); } else { + println!("{}: Copy TCB", context.id.into()); let parent_tcb_addr = crate::USER_TCB_OFFSET + ppid.into() * PAGE_SIZE; unsafe { intrinsics::copy(parent_tcb_addr as *const u8, @@ -696,11 +709,13 @@ fn fexec_noreturn( let rounded_size = ((aligned_size + PAGE_SIZE - 1)/PAGE_SIZE) * PAGE_SIZE; let rounded_offset = rounded_size - aligned_size; + // TODO: Make sure size is not greater than USER_TLS_SIZE + let tls_addr = crate::USER_TLS_OFFSET + context.id.into() * crate::USER_TLS_SIZE; let tls = context::memory::Tls { master: VirtualAddress::new(segment.p_vaddr as usize), file_size: segment.p_filesz as usize, mem: context::memory::Memory::new( - VirtualAddress::new(crate::USER_TLS_OFFSET), + VirtualAddress::new(tls_addr), rounded_size as usize, EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE, true @@ -709,7 +724,7 @@ fn fexec_noreturn( }; unsafe { - *(tcb_addr as *mut usize) = crate::USER_TLS_OFFSET + tls.mem.size(); + *(tcb_addr as *mut usize) = tls.mem.start_address().get() + tls.mem.size(); } tls_option = Some(tls);