Skip to content
Snippets Groups Projects
Verified Commit b930cc98 authored by Jacob Lorentzon's avatar Jacob Lorentzon
Browse files

Correctly preserve and set MXCSR and FCW.

parent 3701ea3b
No related branches found
No related tags found
1 merge request!343Userspace fexec
...@@ -8,10 +8,22 @@ use core::arch::global_asm; ...@@ -8,10 +8,22 @@ use core::arch::global_asm;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
global_asm!(" global_asm!("
.globl _start .globl _start
.type _start, @function
_start: _start:
mov rdi, rsp mov rdi, rsp
and rsp, 0xFFFFFFFFFFFFFFF0 and rsp, 0xFFFFFFFFFFFFFFF0
sub rsp, 8
mov DWORD PTR [rsp], 0x00001F80
ldmxcsr [rsp]
mov WORD PTR [rsp], 0x031F
fldcw [rsp]
add rsp, 8
call relibc_start call relibc_start
.size _start, . - _start
"); ");
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
global_asm!(" global_asm!("
......
...@@ -42,7 +42,7 @@ fn copy_str(cur_pid_fd: usize, new_pid_fd: usize, key: &str) -> Result<()> { ...@@ -42,7 +42,7 @@ fn copy_str(cur_pid_fd: usize, new_pid_fd: usize, key: &str) -> Result<()> {
Ok(()) Ok(())
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn copy_float_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> { fn copy_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> {
// Copy environment registers. // Copy environment registers.
{ {
let cur_env_regs_fd = FdGuard::new(syscall::dup(cur_pid_fd, b"regs/env")?); let cur_env_regs_fd = FdGuard::new(syscall::dup(cur_pid_fd, b"regs/env")?);
...@@ -52,15 +52,6 @@ fn copy_float_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> { ...@@ -52,15 +52,6 @@ fn copy_float_env_regs(cur_pid_fd: usize, new_pid_fd: usize) -> Result<()> {
let _ = syscall::read(*cur_env_regs_fd, &mut env_regs)?; let _ = syscall::read(*cur_env_regs_fd, &mut env_regs)?;
let _ = syscall::write(*new_env_regs_fd, &env_regs)?; let _ = syscall::write(*new_env_regs_fd, &env_regs)?;
} }
// Copy float registers.
{
let cur_float_regs_fd = FdGuard::new(syscall::dup(cur_pid_fd, b"regs/float")?);
let new_float_regs_fd = FdGuard::new(syscall::dup(new_pid_fd, b"regs/float")?);
let mut float_regs = syscall::FloatRegisters::default();
let _ = syscall::read(*cur_float_regs_fd, &mut float_regs)?;
let _ = syscall::write(*new_float_regs_fd, &float_regs)?;
}
Ok(()) Ok(())
} }
...@@ -102,7 +93,7 @@ pub unsafe fn pte_clone_impl(stack: *mut usize) -> Result<usize> { ...@@ -102,7 +93,7 @@ pub unsafe fn pte_clone_impl(stack: *mut usize) -> Result<usize> {
let _ = syscall::write(*new_filetable_sel_fd, &usize::to_ne_bytes(*cur_filetable_fd))?; let _ = syscall::write(*new_filetable_sel_fd, &usize::to_ne_bytes(*cur_filetable_fd))?;
} }
copy_float_env_regs(*cur_pid_fd, *new_pid_fd)?; copy_env_regs(*cur_pid_fd, *new_pid_fd)?;
// Unblock context. // Unblock context.
syscall::kill(new_pid, SIGCONT)?; syscall::kill(new_pid, SIGCONT)?;
...@@ -204,7 +195,7 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> { ...@@ -204,7 +195,7 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
let buf = create_set_addr_space_buf(*new_addr_space_fd, fork_ret as usize, initial_rsp as usize); let buf = create_set_addr_space_buf(*new_addr_space_fd, fork_ret as usize, initial_rsp as usize);
let _ = syscall::write(*new_addr_space_sel_fd, &buf)?; let _ = syscall::write(*new_addr_space_sel_fd, &buf)?;
} }
copy_float_env_regs(*cur_pid_fd, *new_pid_fd)?; copy_env_regs(*cur_pid_fd, *new_pid_fd)?;
} }
// Copy the file table. We do this last to ensure that all previously used file descriptors are // Copy the file table. We do this last to ensure that all previously used file descriptors are
// closed. The only exception -- the filetable selection fd and the current filetable fd -- // closed. The only exception -- the filetable selection fd and the current filetable fd --
...@@ -248,7 +239,10 @@ fork_wrapper: ...@@ -248,7 +239,10 @@ fork_wrapper:
push r14 push r14
push r15 push r15
sub rsp, 16 sub rsp, 32
stmxcsr [rsp+16]
fnstcw [rsp+24]
mov rdi, rsp mov rdi, rsp
call __relibc_internal_fork_impl call __relibc_internal_fork_impl
...@@ -258,9 +252,13 @@ fork_ret: ...@@ -258,9 +252,13 @@ fork_ret:
mov rdi, [rsp] mov rdi, [rsp]
mov rsi, [rsp + 8] mov rsi, [rsp + 8]
call __relibc_internal_fork_hook call __relibc_internal_fork_hook
ldmxcsr [rsp+16]
fldcw [rsp+24]
xor rax, rax xor rax, rax
2: 2:
add rsp, 16 add rsp, 32
pop r15 pop r15
pop r14 pop r14
pop r13 pop r13
......
...@@ -45,9 +45,7 @@ where ...@@ -45,9 +45,7 @@ where
}; };
let memory_fd = FdGuard::new(syscall::dup(*grants_fd, b"mem")?); let memory_fd = FdGuard::new(syscall::dup(*grants_fd, b"mem")?);
let instruction_ptr = usize::try_from(header.e_entry).map_err(|_| Error::new(ENOEXEC))?; // Never allow more than 1 MiB of program headers.
// Never allow more than 1 MiB of program headers. TODO: Capabilities again?
const MAX_PH_SIZE: usize = 1024 * 1024; const MAX_PH_SIZE: usize = 1024 * 1024;
let phentsize = u64::from(header.e_phentsize) as usize; let phentsize = u64::from(header.e_phentsize) as usize;
let phnum = u64::from(header.e_phnum) as usize; let phnum = u64::from(header.e_phnum) as usize;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment