mirror of
https://github.com/XunilGroup/XunilOS.git
synced 2026-04-25 11:49:03 +02:00
Add better register clobbering to syscall calling in libxunil, add header magic to verify each free/malloc/realloc/calloc statement, add our own memcpy, memcmp, memset, memmove
This commit is contained in:
Submodule user/apps/doomgeneric updated: f67aed3904...146c36bfda
@@ -539,7 +539,7 @@ unsafe extern "C" fn strdup(s: *const u8) -> *mut u8 {
|
|||||||
if memory.is_null() {
|
if memory.is_null() {
|
||||||
return null_mut();
|
return null_mut();
|
||||||
}
|
}
|
||||||
memcpy(memory, s, len + 1);
|
unsafe { memcpy(memory, s, len + 1) };
|
||||||
memory
|
memory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use core::{mem, ptr::null_mut, usize};
|
use core::{ffi::c_int, mem, ptr::null_mut, usize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
heap::{ALLOCATOR, LinkedNode},
|
heap::{ALLOCATOR, LinkedNode},
|
||||||
@@ -12,10 +12,15 @@ pub fn sbrk(increment: i64) -> isize {
|
|||||||
|
|
||||||
const MAX_SIZE: u64 = 18446744073709551615;
|
const MAX_SIZE: u64 = 18446744073709551615;
|
||||||
|
|
||||||
|
const HEADER_MAGIC_ALLOC: u64 = 0xBADC0FFEE0DDF00D;
|
||||||
|
const HEADER_MAGIC_FREE: u64 = 0xFEE1DEADCAFEBABE;
|
||||||
|
|
||||||
#[repr(C, align(16))]
|
#[repr(C, align(16))]
|
||||||
struct Header {
|
struct Header {
|
||||||
size: usize,
|
magic: u64,
|
||||||
_pad: usize,
|
_pad: u64,
|
||||||
|
alloc_size: usize,
|
||||||
|
region_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
@@ -34,7 +39,7 @@ pub extern "C" fn calloc(count: u64, size: u64) -> *mut u8 {
|
|||||||
return null_mut();
|
return null_mut();
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(ptr, 0, total as usize);
|
unsafe { memset(ptr, 0, total as usize) };
|
||||||
ptr
|
ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,9 +51,18 @@ pub extern "C" fn free(ptr: *mut u8) {
|
|||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let header_ptr = (ptr as usize - mem::size_of::<Header>()) as *mut Header;
|
let header_ptr = (ptr as usize - mem::size_of::<Header>()) as *mut Header;
|
||||||
let total = (*header_ptr).size;
|
if (header_ptr as usize) & 0xF != 0 {
|
||||||
|
core::hint::unreachable_unchecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*header_ptr).magic != HEADER_MAGIC_ALLOC {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let region_size = (*header_ptr).region_size;
|
||||||
|
(*header_ptr).magic = HEADER_MAGIC_FREE;
|
||||||
let mut allocator = ALLOCATOR.lock();
|
let mut allocator = ALLOCATOR.lock();
|
||||||
allocator.add_free_memory_region(header_ptr as usize, total);
|
allocator.add_free_memory_region(header_ptr as usize, region_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,8 +85,10 @@ pub extern "C" fn malloc(size: u64) -> *mut u8 {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let header_ptr = region.start as *mut Header;
|
let header_ptr = region.start as *mut Header;
|
||||||
header_ptr.write(Header {
|
header_ptr.write(Header {
|
||||||
size: region.end - region.start,
|
magic: HEADER_MAGIC_ALLOC,
|
||||||
_pad: 0,
|
_pad: 0,
|
||||||
|
alloc_size: (region.end - region.start).saturating_sub(hdr),
|
||||||
|
region_size: region.end - region.start,
|
||||||
});
|
});
|
||||||
return (region.start + hdr) as *mut u8;
|
return (region.start + hdr) as *mut u8;
|
||||||
}
|
}
|
||||||
@@ -111,30 +127,6 @@ pub extern "C" fn malloc(size: u64) -> *mut u8 {
|
|||||||
malloc(size)
|
malloc(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
pub extern "C" fn memcpy(dest_str: *mut u8, src_str: *const u8, n: usize) -> *mut u8 {
|
|
||||||
unsafe { core::ptr::copy(src_str, dest_str, n) };
|
|
||||||
dest_str
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
|
||||||
pub extern "C" fn memset(dst: *mut u8, c: i64, n: usize) -> *mut u8 {
|
|
||||||
if dst.is_null() || n == 0 {
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let val = c as u8;
|
|
||||||
let mut i = 0usize;
|
|
||||||
while i < n {
|
|
||||||
*dst.add(i) = val;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dst
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn realloc(ptr: *mut u8, size: usize) -> *mut u8 {
|
pub unsafe extern "C" fn realloc(ptr: *mut u8, size: usize) -> *mut u8 {
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
@@ -149,10 +141,14 @@ pub unsafe extern "C" fn realloc(ptr: *mut u8, size: usize) -> *mut u8 {
|
|||||||
unsafe {
|
unsafe {
|
||||||
let hdr = mem::size_of::<Header>();
|
let hdr = mem::size_of::<Header>();
|
||||||
let header_ptr = (ptr as usize - hdr) as *mut Header;
|
let header_ptr = (ptr as usize - hdr) as *mut Header;
|
||||||
let total = (*header_ptr).size;
|
|
||||||
let old_payload = total.saturating_sub(hdr);
|
|
||||||
|
|
||||||
if size <= old_payload {
|
if (*header_ptr).magic != HEADER_MAGIC_ALLOC {
|
||||||
|
return null_mut();
|
||||||
|
}
|
||||||
|
|
||||||
|
let old_alloc_size = (*header_ptr).alloc_size;
|
||||||
|
|
||||||
|
if size <= old_alloc_size {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +157,102 @@ pub unsafe extern "C" fn realloc(ptr: *mut u8, size: usize) -> *mut u8 {
|
|||||||
return null_mut();
|
return null_mut();
|
||||||
}
|
}
|
||||||
|
|
||||||
core::ptr::copy_nonoverlapping(ptr, new_ptr, old_payload);
|
core::ptr::copy_nonoverlapping(ptr, new_ptr, old_alloc_size);
|
||||||
free(ptr);
|
free(ptr);
|
||||||
new_ptr
|
new_ptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub unsafe extern "C" fn memset(dest: *mut u8, c: c_int, n: usize) -> *mut u8 {
|
||||||
|
if n == 0 {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
if dest.is_null() {
|
||||||
|
return null_mut();
|
||||||
|
}
|
||||||
|
|
||||||
|
let byte = c as u8;
|
||||||
|
let mut i = 0usize;
|
||||||
|
while i < n {
|
||||||
|
unsafe { core::ptr::write_volatile(dest.add(i), byte) };
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
|
||||||
|
if n == 0 {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
if dest.is_null() || src.is_null() {
|
||||||
|
return null_mut();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut i = 0usize;
|
||||||
|
while i < n {
|
||||||
|
let v = unsafe { core::ptr::read_volatile(src.add(i)) };
|
||||||
|
unsafe { core::ptr::write_volatile(dest.add(i), v) };
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
|
||||||
|
if n == 0 {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
if dest.is_null() || src.is_null() {
|
||||||
|
return null_mut();
|
||||||
|
}
|
||||||
|
|
||||||
|
let dest_addr = dest as usize;
|
||||||
|
let src_addr = src as usize;
|
||||||
|
|
||||||
|
if dest_addr == src_addr {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
if dest_addr < src_addr || dest_addr >= src_addr.saturating_add(n) {
|
||||||
|
let mut i = 0usize;
|
||||||
|
while i < n {
|
||||||
|
let v = unsafe { core::ptr::read_volatile(src.add(i)) };
|
||||||
|
unsafe { core::ptr::write_volatile(dest.add(i), v) };
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut i = n;
|
||||||
|
while i != 0 {
|
||||||
|
i -= 1;
|
||||||
|
let v = unsafe { core::ptr::read_volatile(src.add(i)) };
|
||||||
|
unsafe { core::ptr::write_volatile(dest.add(i), v) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest
|
||||||
|
}
|
||||||
|
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub unsafe extern "C" fn memcmp(a: *const u8, b: *const u8, n: usize) -> i32 {
|
||||||
|
if n == 0 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if a.is_null() || b.is_null() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut i = 0usize;
|
||||||
|
while i < n {
|
||||||
|
let av = unsafe { core::ptr::read_volatile(a.add(i)) };
|
||||||
|
let bv = unsafe { core::ptr::read_volatile(b.add(i)) };
|
||||||
|
if av != bv {
|
||||||
|
return av as i32 - bv as i32;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ pub unsafe fn syscall0(num: usize) -> isize {
|
|||||||
"int 0x80",
|
"int 0x80",
|
||||||
in("rax") num,
|
in("rax") num,
|
||||||
lateout("rax") ret,
|
lateout("rax") ret,
|
||||||
out("rdi") _, out("rcx") _, out("rdx") _, out("rsi") _,
|
clobber_abi("sysv64"),
|
||||||
out("r8") _, out("r9") _, out("r10") _, out("r11") _,
|
|
||||||
options(nostack)
|
options(nostack)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -50,8 +49,7 @@ pub unsafe fn syscall1(num: usize, arg0: isize) -> isize {
|
|||||||
in("rax") num,
|
in("rax") num,
|
||||||
in("rdi") arg0,
|
in("rdi") arg0,
|
||||||
lateout("rax") ret,
|
lateout("rax") ret,
|
||||||
out("rcx") _, out("rdx") _, out("rsi") _,
|
clobber_abi("sysv64"),
|
||||||
out("r8") _, out("r9") _, out("r10") _, out("r11") _,
|
|
||||||
options(nostack)
|
options(nostack)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -70,6 +68,7 @@ pub unsafe fn syscall3(num: usize, arg0: isize, arg1: isize, arg2: isize) -> isi
|
|||||||
in("rsi") arg1,
|
in("rsi") arg1,
|
||||||
in("rdx") arg2,
|
in("rdx") arg2,
|
||||||
lateout("rax") ret,
|
lateout("rax") ret,
|
||||||
|
clobber_abi("sysv64"),
|
||||||
options(nostack)
|
options(nostack)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user