diff --git a/resolve-cveassert/libresolve/CMakeLists.txt b/resolve-cveassert/libresolve/CMakeLists.txt index 53baf51e..f123038d 100644 --- a/resolve-cveassert/libresolve/CMakeLists.txt +++ b/resolve-cveassert/libresolve/CMakeLists.txt @@ -3,6 +3,31 @@ include(GNUInstallDirs) include(ExternalProject) +include(FetchContent) + +#### Fetching and building mimalloc project +FetchContent_Declare( + mimalloc + GIT_REPOSITORY https://github.com/microsoft/mimalloc.git + GIT_TAG v3.3.2 +) + +## Force static build +set(MI_BUILD_SHARED OFF CACHE BOOL "" FORCE) +set(MI_BUILD_STATIC ON CACHE BOOL "" FORCE) + +FetchContent_MakeAvailable(mimalloc) + +# Add the shim source to the mimalloc proj +target_sources(mimalloc-static PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/mi_shim.c +) + +## mimalloc proj must be PIC to ensure compatibility with libresolve +set_target_properties(mimalloc-static PROPERTIES + POSITION_INDEPENDENT_CODE ON + OUTPUT_NAME mimalloc +) # Map CMake build type to Cargo flags if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "") @@ -24,17 +49,24 @@ file(GLOB_RECURSE RUST_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/sr add_custom_command( OUTPUT ${RUST_LIB} COMMAND - ${CMAKE_COMMAND} -E env CARGO_TARGET_DIR=${RUST_OUT_DIR} cargo build ${CARGO_FLAGS} + ${CMAKE_COMMAND} -E env + CARGO_TARGET_DIR=${RUST_OUT_DIR} + MIMALLOC_LIB_DIR=$ + cargo build ${CARGO_FLAGS} WORKING_DIRECTORY ${RUST_CRATE_DIR} COMMENT "Building libresolve.so" VERBATIM - DEPENDS ${RUST_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.lock ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml ${CMAKE_CURRENT_SOURCE_DIR}/rust-toolchain.toml + DEPENDS mimalloc-static ${RUST_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.lock ${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml ${CMAKE_CURRENT_SOURCE_DIR}/rust-toolchain.toml ) add_custom_target(test-libresolve - COMMAND cargo test + COMMAND + ${CMAKE_COMMAND} -E env + MIMALLOC_LIB_DIR=${MIMALLOC_LIB_DIR} # Note: Pass the static mimalloc loc so that build.rs does not panic + cargo test WORKING_DIRECTORY ${RUST_CRATE_DIR} COMMENT "Running regression tests for libresolve" ) add_custom_target(libresolve ALL DEPENDS ${RUST_LIB}) +add_dependencies(libresolve mimalloc-static) install(FILES ${RUST_LIB} DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/resolve-cveassert/libresolve/Cargo.lock b/resolve-cveassert/libresolve/Cargo.lock index 7c237a0b..bd01d043 100644 --- a/resolve-cveassert/libresolve/Cargo.lock +++ b/resolve-cveassert/libresolve/Cargo.lock @@ -73,6 +73,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cc" +version = "1.2.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -102,6 +112,12 @@ dependencies = [ "log", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -263,6 +279,7 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" name = "resolve" version = "0.1.0" dependencies = [ + "cc", "env_logger", "libc", "log", @@ -301,6 +318,12 @@ version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + [[package]] name = "syn" version = "2.0.111" diff --git a/resolve-cveassert/libresolve/Cargo.toml b/resolve-cveassert/libresolve/Cargo.toml index 47c09c4b..fd810394 100644 --- a/resolve-cveassert/libresolve/Cargo.toml +++ b/resolve-cveassert/libresolve/Cargo.toml @@ -1,5 +1,6 @@ [package] name = "resolve" +build = "src/build.rs" version = "0.1.0" edition = "2024" @@ -7,6 +8,7 @@ edition = "2024" crate-type = ["cdylib"] [dependencies] +cc = "1.2.63" env_logger = "0.11.8" libc = "0.2.174" log = "0.4.29" diff --git a/resolve-cveassert/libresolve/mi_shim.c b/resolve-cveassert/libresolve/mi_shim.c new file mode 100644 index 00000000..e4c90710 --- /dev/null +++ b/resolve-cveassert/libresolve/mi_shim.c @@ -0,0 +1,106 @@ +// Copyright (c) 2025 Riverside Research. +// LGPL-3; See LICENSE.txt in the repo root for details. + +#include "mimalloc.h" +#include "mimalloc/internal.h" +#include +#include +#include + +extern void* __resolve_malloc(size_t); +extern void __resolve_free(void*); + + +typedef struct { + void *base; + void *limit; + size_t size; +} mi_alloc_bounds_t; + + +mi_alloc_bounds_t mi_get_alloc_bounds(void* p) { + mi_alloc_bounds_t bounds; + mi_alloc_bounds_t empty = { .base = (void*) -1, .limit = (void*)-1, .size = 0 }; + + // Check if ptr is owned by mimalloc + if (!mi_is_in_heap_region(p)) { + return empty; + } + + // Recover the page information for the pointer. + mi_page_t *page = _mi_ptr_page(p); + + if (page == NULL) { + return empty; + } + + // _mi_page_ptr_unalign recovers the corresponding + // block for base and interior pointers + mi_block_t *base = _mi_page_ptr_unalign(page, p); + if (!base) { return empty; } + + bounds.base = (void *)base; + bounds.size = mi_usable_size(base); + bounds.limit = (void *)base + bounds.size; + return bounds; +} + +bool mi_is_heap_owned(const void* p) { + return _mi_ptr_page(p) != NULL; +} + +int __vasprintf(char **strp, const char *fmt, va_list ap) +{ + va_list ap_copy; + va_copy(ap_copy, ap); + + int len = vsnprintf(NULL, 0, fmt, ap_copy); + va_end(ap_copy); + + if (len < 0) { + // to match glibc behavior + *strp = NULL; + return -1; + } + + char *buf = __resolve_malloc((size_t)len + 1); + if (!buf) { return -1; } + + va_copy(ap_copy, ap); + + int written = vsnprintf(buf, (size_t)len + 1, fmt, ap_copy); + + va_end(ap_copy); + + if (written < 0) { + __resolve_free(buf); + return -1; + } + + *strp = buf; + return written; +} + +/* debugging function to help check if a pointer the + base address or an offset into the block +*/ +bool mi_is_block_start(void *p) { + if (p == NULL) { return false; } + + // Recover page information + mi_page_t *page = _mi_ptr_page(p); + + if (page == NULL) { return false; } + + // Compute the block index + const size_t block_size = page->block_size; + uintptr_t page_start = (uintptr_t)page->page_start; + size_t block_index = ((uintptr_t)p - page_start) / block_size; + + // Compute the canonical base. + uintptr_t base = page_start + block_index * block_size; + + // Compare to pointer + return base == (uintptr_t)p; +} + diff --git a/resolve-cveassert/libresolve/src/build.rs b/resolve-cveassert/libresolve/src/build.rs new file mode 100644 index 00000000..ee879105 --- /dev/null +++ b/resolve-cveassert/libresolve/src/build.rs @@ -0,0 +1,6 @@ +fn main() { + let dir = std::env::var("MIMALLOC_LIB_DIR").unwrap(); + println!("cargo::warning=LINKING_MIMALLOC_ARCHIVE"); + println!("cargo::rustc-link-search=native={}", dir); + println!("cargo::rustc-link-lib=static=mimalloc"); +} diff --git a/resolve-cveassert/libresolve/src/remediate.rs b/resolve-cveassert/libresolve/src/remediate.rs index 759f2fb7..a12401c3 100644 --- a/resolve-cveassert/libresolve/src/remediate.rs +++ b/resolve-cveassert/libresolve/src/remediate.rs @@ -1,17 +1,61 @@ // Copyright (c) 2025 Riverside Research. // LGPL-3; See LICENSE.txt in the repo root for details. + use libc::{ c_char, c_int, c_void, calloc, free, malloc, mmap, munmap, off_t, realloc, strdup, strlen, strndup, strnlen, }; +use std::ffi::{CStr, VaList}; + use crate::shadowobjs::{ ALIVE_OBJ_LIST, AllocType, FREED_OBJ_LIST, GLOBALS, SHADOW_STACK, ShadowObject, Vaddr, lookup_global, }; use log::{info, warn}; -use std::ffi::CStr; + +#[derive(PartialEq)] +#[repr(C)] +pub struct AllocBounds { + base: *mut c_void, + limit: *mut c_void, + size: usize, +} + +impl From for ShadowObjBounds { + fn from(bounds: AllocBounds) -> Self { + ShadowObjBounds { + base: bounds.base, + limit: bounds.limit, + } + } +} +// implement the From Trait for AllocBounds + +#[link(name = "mimalloc")] +unsafe extern "C" { + // Mimalloc public API + fn mi_malloc(size: usize) -> *mut c_void; + fn mi_calloc(size: usize, count: usize) -> *mut c_void; + fn mi_realloc(ptr: *mut c_void, size: usize) -> *mut c_void; + fn mi_strdup(ptr: *mut c_char) -> *mut c_char; + fn mi_strndup(ptr: *mut c_char, size: usize) -> *mut c_char; + + fn mi_aligned_alloc(alignment: usize, n: usize) -> *mut c_void; + fn mi_reallocarray(ptr: *mut c_void, n: usize, size: usize) -> *mut c_void; + fn mi_posix_memalign(memptr: *mut *mut c_void, alignment: usize, size: usize) -> c_int; + + fn mi_free(ptr: *mut c_void); + fn mi_new(size: usize) -> *mut c_void; + fn mi_delete(ptr: *mut c_void); + + // mi_shim.c API + fn mi_is_in_heap_region(ptr: *mut c_void) -> bool; + fn mi_get_alloc_bounds(ptr: *mut c_void) -> AllocBounds; + fn __vasprintf(strp: *mut *mut c_char, fmt: *const c_char, args: VaList<'_>) -> c_int; + fn mi_is_block_start(ptr: *mut c_void) -> bool; +} /** * @brief - Registers stack allocations in shadow memory @@ -50,22 +94,164 @@ pub extern "C" fn __resolve_invalidate_stack_range(ptr: *mut c_void, size: usize SHADOW_STACK.with_borrow_mut(|ss| ss.invalidate_at(base, size)); - info!( - "[STACK] Unregistered stack object: addr={:p}, size={}", - ptr, size - ); + info!("[STACK] Free addr={:p}, size={}", ptr, size); +} + +#[unsafe(no_mangle)] +pub extern "C" fn __resolve_getline( + lineptr: *mut *mut c_char, + size: *mut size_t, + stream: *mut FILE, +) -> ssize_t { + if lineptr.is_null() || size.is_null() || stream.is_null() { + return -1; + } + + unsafe { + if (*lineptr).is_null() || *size == 0 { + *size = 128; + *lineptr = __resolve_malloc(*size) as *mut c_char; + + // check if the pointer is null + if (*lineptr).is_null() { + return -1; + } + } + + let mut pos: size_t = 0; + let mut c: c_int; + + loop { + c = fgetc(stream); + if c == EOF { + break; + } + + if pos + 1 >= *size { + // Expand buffer + let new_size = *size * 2; + let new_buf = __resolve_realloc(*lineptr as *mut c_void, new_size); + + if new_buf.is_null() { + return -1; + } + + *lineptr = new_buf as *mut c_char; + *size = new_size; + } + + // (*lineptr)[pos++] = (char)c; + (*lineptr).add(pos).write(c as c_char); + pos += 1; + + if c == b'\n' as c_int { + break; + } + } + + if pos == 0 && c == EOF { + // No data read + return -1; + } + + (*lineptr).add(pos).write(0); // (*lineptr)[pos] = '\0' + } + pos as ssize_t +} + +#[unsafe(no_mangle)] +pub extern "C" fn __resolve_getdelim( + lineptr: *mut *mut c_char, + size: *mut size_t, + delim: c_int, + stream: *mut FILE, +) -> ssize_t { + if lineptr.is_null() || size.is_null() || stream.is_null() { + return -1; + } + + unsafe { + if (*lineptr).is_null() || *size == 0 { + *size = 128; + *lineptr = __resolve_malloc(*size) as *mut c_char; + + if (*lineptr).is_null() { + return -1; + } + } + + let mut pos: size_t = 0; + let mut c: c_int; + + loop { + c = fgetc(stream); + if c == EOF { + break; + } + + if pos + 1 >= *size { + let new_size = *size * 2; + let new_buf = __resolve_realloc(*lineptr as *mut c_void, new_size); + + if new_buf.is_null() { + return -1; + } + + *lineptr = new_buf as *mut c_char; + *size = new_size; + } + + (*lineptr).add(pos).write(c as c_char); + pos += 1; + + if c == delim { + break; + } + } + + (*lineptr).add(pos).write(0); + pos as ssize_t + } +} + +#[unsafe(no_mangle)] +pub unsafe extern "C" fn __resolve_asprintf( + strp: *mut *mut c_char, + fmt: *const c_char, + args: ... +) -> c_int { + return unsafe { __vasprintf(strp, fmt, args) }; +} + +#[unsafe(no_mangle)] +pub extern "C" fn __resolve_aligned_alloc(alignment: usize, n: usize) -> *mut c_void { + return unsafe { mi_aligned_alloc(alignment, n) }; +} + +#[unsafe(no_mangle)] +pub extern "C" fn __resolve_posix_memalign( + memptr: *mut *mut c_void, + alignment: usize, + size: usize, +) -> c_int { + return unsafe { mi_posix_memalign(memptr, alignment, size) }; +} + +#[unsafe(no_mangle)] +pub extern "C" fn __resolve_reallocarray(ptr: *mut c_void, n: usize, size: usize) -> *mut c_void { + return unsafe { mi_reallocarray(ptr, n, size) }; } /** - * @brief - RESOLVE wrapper for libc malloc - * @input - * - size: size of requested heap allocation in bytes - * @return - * - pointer to requested heap allocation + * @brief - Allocator logging interface for malloc + * @input - size of the allocation in bytes + * @return - ptr to the allocation */ #[unsafe(no_mangle)] pub extern "C" fn __resolve_malloc(size: usize) -> *mut c_void { - let ptr = unsafe { malloc(size + 1) }; + // SAFETY: + // - 'ptr' allocated by mimalloc + let ptr = unsafe { mi_malloc(size) }; if ptr.is_null() { return ptr; @@ -77,10 +263,24 @@ pub extern "C" fn __resolve_malloc(size: usize) -> *mut c_void { } info!( - "[HEAP] Registered heap object (malloc): addr={:p}, size={}", + "[HEAP] Registered heap object (mi_malloc): addr={:p}, size={}", ptr, size ); + //info!("[RESOLVE] bounds: (0x{:x}, 0x{:x})", bounds_info.base as Vaddr, bounds_info.limit as Vaddr); + //info!("[RESOLVE] block index: {}", bounds_info.block_index); + //info!("[RESOLVE] block size: {}", bounds_info.block_size); + ptr +} + +#[unsafe(no_mangle)] +pub extern "C" fn __resolve_new(size: usize) -> *mut c_void { + let ptr = unsafe { mi_new(size) }; + + if ptr.is_null() { + return ptr; + } + ptr } @@ -127,9 +327,16 @@ pub extern "C" fn __resolve_free(ptr: *mut c_void) -> () { freed_guard.add_shadow_object(AllocType::Unallocated, ptr as Vaddr, obj_size.unwrap_or(0)); } - let _ = unsafe { free(ptr) }; + let _ = unsafe { mi_free(ptr) }; } +#[unsafe(no_mangle)] +pub extern "C" fn __resolve_delete(ptr: *mut c_void) -> () { + if ptr.is_null() { + return; + } + let _ = unsafe { mi_free(ptr) }; +} /** * @brief - RESOLVE wrapper for libc realloc * @input @@ -147,8 +354,12 @@ pub extern "C" fn __resolve_realloc(ptr: *mut c_void, size: usize) -> *mut c_voi // Consideration: Pointer passed in may be invalidated so we need a mechanism // to remove the shadow object for the orignal allocation - let realloc_ptr = unsafe { realloc(ptr, size + 1) }; + let realloc_ptr = unsafe { mi_realloc(ptr, size) }; + info!( + "[RESOLVE] old = 0x{:x}, new = 0x{:x}, size = {}", + ptr as Vaddr, realloc_ptr as Vaddr, size + ); if realloc_ptr.is_null() { return realloc_ptr; } @@ -177,18 +388,18 @@ pub extern "C" fn __resolve_realloc(ptr: *mut c_void, size: usize) -> *mut c_voi * requested size */ #[unsafe(no_mangle)] -pub extern "C" fn __resolve_calloc(nelems: usize, elsize: usize) -> *mut c_void { - let ptr = unsafe { calloc(nelems, elsize) }; - let size = nelems * elsize; +pub extern "C" fn __resolve_calloc(n_items: usize, item_size: usize) -> *mut c_void { + let ptr = unsafe { mi_calloc(n_items, item_size) }; + //let size = n_items * item_size; if ptr.is_null() { return ptr; } - { - let mut obj_list = ALIVE_OBJ_LIST.lock(); - obj_list.add_shadow_object(AllocType::Heap, ptr as Vaddr, size); - } + //{ + // let mut obj_list = ALIVE_OBJ_LIST.lock(); + // obj_list.add_shadow_object(AllocType::Heap, ptr as Vaddr, size); + //} info!( "[HEAP] Registered heap object (calloc): addr={:p}, size={}", @@ -207,7 +418,7 @@ pub extern "C" fn __resolve_calloc(nelems: usize, elsize: usize) -> *mut c_void */ #[unsafe(no_mangle)] pub extern "C" fn __resolve_strdup(ptr: *mut c_char) -> *mut c_char { - let string_ptr = unsafe { strdup(ptr) }; + let string_ptr = unsafe { mi_strdup(ptr) }; if string_ptr.is_null() { return string_ptr; @@ -216,11 +427,11 @@ pub extern "C" fn __resolve_strdup(ptr: *mut c_char) -> *mut c_char { // +1 to include null termination byte. We should allow program to read this value. // Otherwise how would the program find the end of the string? // Although writing it to something else is probably a bad idea, this too should be allowed. - let sizeofstr = unsafe { strlen(ptr) + 1 }; - { - let mut obj_list = ALIVE_OBJ_LIST.lock(); - obj_list.add_shadow_object(AllocType::Heap, string_ptr as Vaddr, sizeofstr); - } + // let sizeofstr = unsafe { strlen(ptr) + 1 }; + // { + // let mut obj_list = ALIVE_OBJ_LIST.lock(); + // obj_list.add_shadow_object(AllocType::Heap, string_ptr as Vaddr, sizeofstr); + // } info!( "[HEAP] Registered heap object (strdup): addr={:p}, size={}", @@ -241,7 +452,7 @@ pub extern "C" fn __resolve_strdup(ptr: *mut c_char) -> *mut c_char { */ #[unsafe(no_mangle)] pub extern "C" fn __resolve_strndup(ptr: *mut c_char, size: usize) -> *mut c_char { - let string_ptr = unsafe { strndup(ptr, size + 1) }; + let string_ptr = unsafe { mi_strndup(ptr, size) }; if string_ptr.is_null() { return string_ptr; @@ -251,12 +462,12 @@ pub extern "C" fn __resolve_strndup(ptr: *mut c_char, size: usize) -> *mut c_cha // We don't actually know how much memory the libc will allocate, but // strnlen(ptr, size) + 1 is a safe lower bound. // strlen(string_ptr) + 1 would also be valid I think. - let sizeofstr = unsafe { strnlen(ptr, size) + 1 }; + //let sizeofstr = unsafe { strnlen(ptr, size) + 1 }; - { - let mut obj_list = ALIVE_OBJ_LIST.lock(); - obj_list.add_shadow_object(AllocType::Heap, string_ptr as Vaddr, sizeofstr); - } + //{ + // let mut obj_list = ALIVE_OBJ_LIST.lock(); + // obj_list.add_shadow_object(AllocType::Heap, string_ptr as Vaddr, sizeofstr); + //} info!( "[HEAP] Registered heap object (strndup): addr={:p}, size={}", @@ -394,33 +605,23 @@ pub extern "C" fn __resolve_get_bounds_stack(ptr: *mut c_void) -> ShadowObjBound */ #[unsafe(no_mangle)] pub extern "C" fn __resolve_get_bounds_heap(ptr: *mut c_void) -> ShadowObjBounds { - let sobj_table = ALIVE_OBJ_LIST.lock(); - let Some(sobj) = sobj_table.search_intersection(ptr as Vaddr) else { + if ptr.is_null() { return ShadowObjBounds::null(); - }; + } - return sobj.into(); -} + // SAFETY: + // 'ptr' must point to valid allocation owned by mimalloc + let bounds = unsafe { mi_get_alloc_bounds(ptr) }; + info!( + "[RESOLVE] (ptr: 0x{:x}, lower: 0x{:x}, upper: 0x{:x})", + ptr as Vaddr, bounds.base as Vaddr, bounds.limit as Vaddr + ); -/** - * @brief - Queries recorded globals to find a shadow obj - * where the ptr is within bounds of allocation - * @input - * - ptr: ptr to global allocation - * @return shadow object that satisfies base <= ptr && ptr < limit - * If shadow object cannot be found the function returns - * a shadow object with null base and limit pointers - */ -#[unsafe(no_mangle)] -pub extern "C" fn __resolve_get_bounds_global(ptr: *mut c_void) -> ShadowObjBounds { - match lookup_global(ptr as Vaddr) { - Some(obj) => (&obj).into(), - None => ShadowObjBounds::null(), - } + return sobj.into(); } /** - * @brief - Generic shadow object lookup where we don't know the pointers + * @brief - Generic sobj lookup where we don't know the pointers * allocation type already. Searches stack table ( O(log n) ) * before searching the heap table * @input @@ -438,7 +639,7 @@ pub extern "C" fn __resolve_get_bounds(ptr: *mut c_void) -> ShadowObjBounds { sobj = __resolve_get_bounds_global(ptr) } - sobj + bounds } #[unsafe(no_mangle)] diff --git a/resolve-cveassert/libresolve/src/shadowobjs.rs b/resolve-cveassert/libresolve/src/shadowobjs.rs index b6086294..05f5b8c1 100644 --- a/resolve-cveassert/libresolve/src/shadowobjs.rs +++ b/resolve-cveassert/libresolve/src/shadowobjs.rs @@ -23,11 +23,8 @@ pub enum AllocType { #[derive(Debug, Clone, Copy)] pub struct ShadowObject { - /// Allocation type (Heap, Stack, Global, etc..) pub alloc_type: AllocType, - // Base address of the allocated object mapped to u64 pub base: Vaddr, - /// Last address of the allocated object pub limit: Vaddr, size: usize, } diff --git a/resolve-cveassert/src/InstrumentAllocators.cpp b/resolve-cveassert/src/InstrumentAllocators.cpp index dfd9b4b6..9914a772 100644 --- a/resolve-cveassert/src/InstrumentAllocators.cpp +++ b/resolve-cveassert/src/InstrumentAllocators.cpp @@ -85,6 +85,31 @@ void instrumentLibraryAllocations(Function *F) { false)); wrapLibraryFunction( F, "munmap", FunctionType::get(integerType, {ptrType, sizeType}, false)); + wrapLibraryFunction( + F, "getline", + FunctionType::get(sizeType, {ptrType, ptrType, ptrType}, false)); + wrapLibraryFunction(F, "getdelim", + FunctionType::get(sizeType, + {ptrType, ptrType, sizeType, ptrType}, + false)); + wrapLibraryFunction(F, "new", FunctionType::get(ptrType, {sizeType}, false)); + wrapLibraryFunction(F, "delete", + FunctionType::get(voidType, {ptrType}, false)); + wrapLibraryFunction(F, "asprintf", + FunctionType::get(sizeType, + { + ptrType, + ptrType, + }, + true)); + wrapLibraryFunction(F, "aligned_alloc", + FunctionType::get(ptrType, {sizeType, sizeType}, false)); + wrapLibraryFunction( + F, "reallocarray", + FunctionType::get(ptrType, {ptrType, sizeType, sizeType}, false)); + wrapLibraryFunction( + F, "posix_memalign", + FunctionType::get(sizeType, {ptrType, sizeType, sizeType}, false)); } void instrumentAlloca(Function *F) {