From 67cc6799bd2e5e54b34d60e026aeaf7cb22e1a5e Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Tue, 22 Dec 2020 15:30:40 +0100 Subject: [PATCH] Fix possible UB by checking for null allocating FX. Namely, the global allocator API in Rust, actually only returns a null pointer on failure, rather than wrapping it in a Result, which AllocRef does. Since Box::from_raw(null) is direct UB, this can in theory lead to very strange behavior. --- src/syscall/process.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 19a3210e..79629226 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -87,10 +87,20 @@ pub fn clone(flags: CloneFlags, stack_base: usize) -> Result<ContextId> { arch = context.arch.clone(); if let Some(ref fx) = context.kfx { - let mut new_fx = unsafe { Box::from_raw(crate::ALLOCATOR.alloc(Layout::from_size_align_unchecked(1024, 16)) as *mut [u8; 1024]) }; - for (new_b, b) in new_fx.iter_mut().zip(fx.iter()) { - *new_b = *b; - } + let mut new_fx = unsafe { + let new_fx_ptr = crate::ALLOCATOR.alloc(Layout::from_size_align_unchecked(1024, 16)); + if new_fx_ptr.is_null() { + // FIXME: It's mildly ironic that the only place where clone can fail with + // ENOMEM, is when copying 1024 bytes to merely store vector registers. + // Although in order to achieve full kernel-panic immunity, we'll need to + // completely phase out all usage of liballoc data structures, and use our + // own library/port liballoc, since panicking on OOM is not good for a + // kernel. + return Err(Error::new(ENOMEM)); + } + new_fx_ptr.copy_from_nonoverlapping(fx.as_ptr(), fx.len()); + Box::from_raw(new_fx_ptr as *mut [u8; 1024]) + }; kfx_opt = Some(new_fx); } -- GitLab