mirror of
				https://github.com/GrapheneOS/hardened_malloc.git
				synced 2025-11-04 09:46:32 +01:00 
			
		
		
		
	Compare commits
	
		
			2 commits
		
	
	
		
			5d22d91964
			...
			7d47df270a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							 | 
						7d47df270a | ||
| 
							 | 
						2584fdda8d | 
					 22 changed files with 461 additions and 8 deletions
				
			
		| 
						 | 
				
			
			@ -28,6 +28,7 @@ common_cflags = [
 | 
			
		|||
    "-DN_ARENA=1",
 | 
			
		||||
    "-DCONFIG_STATS=true",
 | 
			
		||||
    "-DCONFIG_SELF_INIT=false",
 | 
			
		||||
    "-DCONFIG_BLOCK_OPS_CHECK_SIZE=false",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
cc_defaults {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								CREDITS
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								CREDITS
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -23,6 +23,30 @@ h_malloc.c open-addressed hash table (regions_grow, regions_insert, regions_find
 | 
			
		|||
    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 | 
			
		||||
*_musl functions extracted from musl and macros removed:
 | 
			
		||||
    Copyright © 2005-2020 Rich Felker, et al.
 | 
			
		||||
 | 
			
		||||
    Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
    a copy of this software and associated documentation files (the
 | 
			
		||||
    "Software"), to deal in the Software without restriction, including
 | 
			
		||||
    without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
    distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
    permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
    the following conditions:
 | 
			
		||||
 | 
			
		||||
    The above copyright notice and this permission notice shall be
 | 
			
		||||
    included in all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
    Contributor list: https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
 | 
			
		||||
 | 
			
		||||
libdivide:
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 2010 - 2019 ridiculous_fish, <libdivide@ridiculousfish.com>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										7
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -89,6 +89,10 @@ ifeq (,$(filter $(CONFIG_SELF_INIT),true false))
 | 
			
		|||
    $(error CONFIG_SELF_INIT must be true or false)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq (,$(filter $(CONFIG_BLOCK_OPS_CHECK_SIZE),true false))
 | 
			
		||||
    $(error CONFIG_BLOCK_OPS_CHECK_SIZE must be true or false)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
CPPFLAGS += \
 | 
			
		||||
    -DCONFIG_SEAL_METADATA=$(CONFIG_SEAL_METADATA) \
 | 
			
		||||
    -DZERO_ON_FREE=$(CONFIG_ZERO_ON_FREE) \
 | 
			
		||||
| 
						 | 
				
			
			@ -108,7 +112,8 @@ CPPFLAGS += \
 | 
			
		|||
    -DCONFIG_CLASS_REGION_SIZE=$(CONFIG_CLASS_REGION_SIZE) \
 | 
			
		||||
    -DN_ARENA=$(CONFIG_N_ARENA) \
 | 
			
		||||
    -DCONFIG_STATS=$(CONFIG_STATS) \
 | 
			
		||||
    -DCONFIG_SELF_INIT=$(CONFIG_SELF_INIT)
 | 
			
		||||
    -DCONFIG_SELF_INIT=$(CONFIG_SELF_INIT) \
 | 
			
		||||
    -DCONFIG_BLOCK_OPS_CHECK_SIZE=$(CONFIG_BLOCK_OPS_CHECK_SIZE)
 | 
			
		||||
 | 
			
		||||
$(OUT)/libhardened_malloc$(SUFFIX).so: $(OBJECTS) | $(OUT)
 | 
			
		||||
	$(CC) $(CFLAGS) $(LDFLAGS) -shared $^ $(LDLIBS) -o $@
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -276,6 +276,9 @@ The following boolean configuration options are available:
 | 
			
		|||
  hardware, which may become drastically lower in the future. Whether or not
 | 
			
		||||
  this feature is enabled, the metadata is all contained within an isolated
 | 
			
		||||
  memory region with high entropy random guard regions around it.
 | 
			
		||||
* `CONFIG_BLOCK_OPS_CHECK_SIZE`: `true` or `false` (default) to ensure length
 | 
			
		||||
  parameter of the memcpy/memmove/memset block operations and their wide
 | 
			
		||||
  variants are within approximate bounds to minimize buffer overflows.
 | 
			
		||||
 | 
			
		||||
The following integer configuration options are available:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,3 +21,4 @@ CONFIG_CLASS_REGION_SIZE := 34359738368 # 32GiB
 | 
			
		|||
CONFIG_N_ARENA := 4
 | 
			
		||||
CONFIG_STATS := false
 | 
			
		||||
CONFIG_SELF_INIT := true
 | 
			
		||||
CONFIG_BLOCK_OPS_CHECK_SIZE := false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,3 +21,4 @@ CONFIG_CLASS_REGION_SIZE := 34359738368 # 32GiB
 | 
			
		|||
CONFIG_N_ARENA := 4
 | 
			
		||||
CONFIG_STATS := false
 | 
			
		||||
CONFIG_SELF_INIT := true
 | 
			
		||||
CONFIG_BLOCK_OPS_CHECK_SIZE := false
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										150
									
								
								h_malloc.c
									
										
									
									
									
								
							
							
						
						
									
										150
									
								
								h_malloc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -528,7 +528,7 @@ static void set_canary(UNUSED const struct slab_metadata *metadata, UNUSED void
 | 
			
		|||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    memcpy((char *)p + size - canary_size, &metadata->canary_value, canary_size);
 | 
			
		||||
    h_memcpy_internal((char *)p + size - canary_size, &metadata->canary_value, canary_size);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -541,7 +541,7 @@ static void check_canary(UNUSED const struct slab_metadata *metadata, UNUSED con
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
    u64 canary_value;
 | 
			
		||||
    memcpy(&canary_value, (const char *)p + size - canary_size, canary_size);
 | 
			
		||||
    h_memcpy_internal(&canary_value, (const char *)p + size - canary_size, canary_size);
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_ARM_MTE
 | 
			
		||||
    if (unlikely(canary_value == 0)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -831,7 +831,7 @@ static inline void deallocate_small(void *p, const size_t *expected_size) {
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
        if (ZERO_ON_FREE && !skip_zero) {
 | 
			
		||||
            memset(p, 0, size - canary_size);
 | 
			
		||||
            h_memset_internal(p, 0, size - canary_size);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1502,7 +1502,7 @@ EXPORT void *h_calloc(size_t nmemb, size_t size) {
 | 
			
		|||
    total_size = adjust_size_for_canary(total_size);
 | 
			
		||||
    void *p = alloc(total_size);
 | 
			
		||||
    if (!ZERO_ON_FREE && likely(p != NULL) && total_size && total_size <= max_slab_size_class) {
 | 
			
		||||
        memset(p, 0, total_size - canary_size);
 | 
			
		||||
        h_memset_internal(p, 0, total_size - canary_size);
 | 
			
		||||
    }
 | 
			
		||||
#ifdef HAS_ARM_MTE
 | 
			
		||||
    // use an assert instead of adding a conditional to memset() above (freed memory is always
 | 
			
		||||
| 
						 | 
				
			
			@ -1624,7 +1624,7 @@ EXPORT void *h_realloc(void *old, size_t size) {
 | 
			
		|||
                mutex_unlock(&ra->lock);
 | 
			
		||||
 | 
			
		||||
                if (memory_remap_fixed(old, old_size, new, size)) {
 | 
			
		||||
                    memcpy(new, old, copy_size);
 | 
			
		||||
                    h_memcpy_internal(new, old, copy_size);
 | 
			
		||||
                    deallocate_pages(old, old_size, old_guard_size);
 | 
			
		||||
                } else {
 | 
			
		||||
                    memory_unmap((char *)old - old_guard_size, old_guard_size);
 | 
			
		||||
| 
						 | 
				
			
			@ -1646,7 +1646,7 @@ EXPORT void *h_realloc(void *old, size_t size) {
 | 
			
		|||
    if (copy_size > 0 && copy_size <= max_slab_size_class) {
 | 
			
		||||
        copy_size -= canary_size;
 | 
			
		||||
    }
 | 
			
		||||
    memcpy(new, old_orig, copy_size);
 | 
			
		||||
    h_memcpy_internal(new, old_orig, copy_size);
 | 
			
		||||
    if (old_size <= max_slab_size_class) {
 | 
			
		||||
        deallocate_small(old, NULL);
 | 
			
		||||
    } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -1874,6 +1874,144 @@ EXPORT size_t h_malloc_object_size_fast(const void *p) {
 | 
			
		|||
    return SIZE_MAX;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
 | 
			
		||||
inline void EXCLUDE_REPLACEMENT *h_memcpy_musl(void *restrict dst, const void *restrict src, size_t len) {
 | 
			
		||||
    unsigned char *d = dst;
 | 
			
		||||
    const unsigned char *s = src;
 | 
			
		||||
 | 
			
		||||
    for (; len; len--) *d++ = *s++;
 | 
			
		||||
 | 
			
		||||
    return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT void *h_memcpy_wrapped(void *restrict dst, const void *restrict src, size_t len) {
 | 
			
		||||
    if(dst == src || len == 0) {
 | 
			
		||||
        return dst;
 | 
			
		||||
    }
 | 
			
		||||
    if (dst < src + len && dst + len > src) {
 | 
			
		||||
        fatal_error("memcpy overlap");
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(src)) {
 | 
			
		||||
        fatal_error("memcpy read overflow");
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(dst)) {
 | 
			
		||||
        fatal_error("memcpy buffer overflow");
 | 
			
		||||
    }
 | 
			
		||||
    return h_memcpy_musl(dst, src, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void EXCLUDE_REPLACEMENT *h_memmove_musl(void *dst, const void *src, size_t len) {
 | 
			
		||||
    char *d = dst;
 | 
			
		||||
    const char *s = src;
 | 
			
		||||
 | 
			
		||||
    if (d < s) {
 | 
			
		||||
        for (; len; len--) *d++ = *s++;
 | 
			
		||||
    } else {
 | 
			
		||||
        while (len) len--, d[len] = s[len];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT void *h_memmove_wrapped(void *dst, const void *src, size_t len) {
 | 
			
		||||
    if(dst == src || len == 0) {
 | 
			
		||||
        return dst;
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(src)) {
 | 
			
		||||
        fatal_error("memmove read overflow");
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(dst)) {
 | 
			
		||||
        fatal_error("memmove buffer overflow");
 | 
			
		||||
    }
 | 
			
		||||
    return h_memmove_musl(dst, src, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline void EXCLUDE_REPLACEMENT *h_memset_musl(void *dst, int value, size_t len) {
 | 
			
		||||
    unsigned char *s = dst;
 | 
			
		||||
 | 
			
		||||
    for (; len; len--, s++) *s = value;
 | 
			
		||||
 | 
			
		||||
    return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT void *h_memset_wrapped(void *dst, int value, size_t len) {
 | 
			
		||||
    if(len == 0) {
 | 
			
		||||
        return dst;
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(dst)) {
 | 
			
		||||
        fatal_error("memset buffer overflow");
 | 
			
		||||
    }
 | 
			
		||||
    return h_memset_musl(dst, value, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline wchar_t EXCLUDE_REPLACEMENT *h_wmemcpy_musl(wchar_t *restrict dst, const wchar_t *restrict src, size_t len) {
 | 
			
		||||
    wchar_t *ret = dst;
 | 
			
		||||
 | 
			
		||||
    while (len--) *dst++ = *src++;
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT wchar_t *h_wmemcpy_wrapped(wchar_t *restrict dst, const wchar_t *restrict src, size_t len) {
 | 
			
		||||
    if(dst == src || len == 0) {
 | 
			
		||||
        return dst;
 | 
			
		||||
    }
 | 
			
		||||
    if (dst < src + len && dst + len > src) {
 | 
			
		||||
        fatal_error("wmemcpy overlap");
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(src)) {
 | 
			
		||||
        fatal_error("wmemcpy read overflow");
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(dst)) {
 | 
			
		||||
        fatal_error("wmemcpy buffer overflow");
 | 
			
		||||
    }
 | 
			
		||||
    return h_wmemcpy_musl(dst, src, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline wchar_t EXCLUDE_REPLACEMENT *h_wmemmove_musl(wchar_t *dst, const wchar_t *src, size_t len) {
 | 
			
		||||
    wchar_t *ret = dst;
 | 
			
		||||
 | 
			
		||||
    if ((uintptr_t)dst-(uintptr_t)src < len * sizeof *dst) {
 | 
			
		||||
        while (len--) dst[len] = src[len];
 | 
			
		||||
    } else {
 | 
			
		||||
	while (len--) *dst++ = *src++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT wchar_t *h_wmemmove_wrapped(wchar_t *dst, const wchar_t *src, size_t len) {
 | 
			
		||||
    if(dst == src || len == 0) {
 | 
			
		||||
        return dst;
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(src)) {
 | 
			
		||||
        fatal_error("wmemmove read overflow");
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(dst)) {
 | 
			
		||||
        fatal_error("wmemmove buffer overflow");
 | 
			
		||||
    }
 | 
			
		||||
    return h_wmemmove_musl(dst, src, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline wchar_t EXCLUDE_REPLACEMENT *h_wmemset_musl(wchar_t *dst, wchar_t value, size_t len) {
 | 
			
		||||
    wchar_t *ret = dst;
 | 
			
		||||
 | 
			
		||||
    while (len--) *dst++ = value;
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
EXPORT wchar_t *h_wmemset_wrapped(wchar_t *dst, wchar_t value, size_t len) {
 | 
			
		||||
    if(len == 0) {
 | 
			
		||||
        return dst;
 | 
			
		||||
    }
 | 
			
		||||
    if (len > malloc_object_size(dst)) {
 | 
			
		||||
        fatal_error("wmemset buffer overflow");
 | 
			
		||||
    }
 | 
			
		||||
    return h_wmemset_musl(dst, value, len);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
EXPORT int h_mallopt(UNUSED int param, UNUSED int value) {
 | 
			
		||||
#ifdef __ANDROID__
 | 
			
		||||
    if (param == M_PURGE) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,6 +15,14 @@ extern "C" {
 | 
			
		|||
#define h_realloc realloc
 | 
			
		||||
#define h_aligned_alloc aligned_alloc
 | 
			
		||||
#define h_free free
 | 
			
		||||
#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
 | 
			
		||||
#define h_memcpy_wrapped memcpy
 | 
			
		||||
#define h_memmove_wrapped memmove
 | 
			
		||||
#define h_memset_wrapped memset
 | 
			
		||||
#define h_wmemcpy_wrapped wmemcpy
 | 
			
		||||
#define h_wmemmove_wrapped wmemmove
 | 
			
		||||
#define h_wmemset_wrapped wmemset
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define h_posix_memalign posix_memalign
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +62,32 @@ __attribute__((alloc_size(2))) void *h_realloc(void *ptr, size_t size);
 | 
			
		|||
__attribute__((malloc)) __attribute__((alloc_size(2))) __attribute__((alloc_align(1)))
 | 
			
		||||
void *h_aligned_alloc(size_t alignment, size_t size);
 | 
			
		||||
void h_free(void *ptr);
 | 
			
		||||
#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
 | 
			
		||||
#if defined(__clang__)
 | 
			
		||||
#define EXCLUDE_REPLACEMENT __attribute__((optnone))
 | 
			
		||||
#elif defined(__GNUC__) || defined(__GNUG__)
 | 
			
		||||
#define EXCLUDE_REPLACEMENT __attribute__((__optimize__("-fno-tree-loop-distribute-patterns")))
 | 
			
		||||
#endif
 | 
			
		||||
void *h_memcpy_musl(void *dst, const void *src, size_t len);
 | 
			
		||||
void *h_memcpy_wrapped(void *dst, const void *src, size_t len);
 | 
			
		||||
void *h_memmove_musl(void *dst, const void *src, size_t len);
 | 
			
		||||
void *h_memmove_wrapped(void *dst, const void *src, size_t len);
 | 
			
		||||
void *h_memset_musl(void *dst, int value, size_t len);
 | 
			
		||||
void *h_memset_wrapped(void *dst, int value, size_t len);
 | 
			
		||||
wchar_t *h_wmemcpy_musl(wchar_t *dst, const wchar_t *src, size_t len);
 | 
			
		||||
wchar_t *h_wmemcpy_wrapped(wchar_t *dst, const wchar_t *src, size_t len);
 | 
			
		||||
wchar_t *h_wmemmove_musl(wchar_t *dst, const wchar_t *src, size_t len);
 | 
			
		||||
wchar_t *h_wmemmove_wrapped(wchar_t *dst, const wchar_t *src, size_t len);
 | 
			
		||||
wchar_t *h_wmemset_musl(wchar_t *dst, wchar_t value, size_t len);
 | 
			
		||||
wchar_t *h_wmemset_wrapped(wchar_t *dst, wchar_t value, size_t len);
 | 
			
		||||
#define h_memcpy_internal h_memcpy_musl
 | 
			
		||||
#define h_memove_internal h_memmove_musl
 | 
			
		||||
#define h_memset_internal h_memset_musl
 | 
			
		||||
#else
 | 
			
		||||
#define h_memcpy_internal __builtin_memcpy
 | 
			
		||||
#define h_memove_internal __builtin_memmove
 | 
			
		||||
#define h_memset_internal __builtin_memset
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// POSIX
 | 
			
		||||
int h_posix_memalign(void **memptr, size_t alignment, size_t size);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								test/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								test/.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -41,4 +41,15 @@ overflow_small_8_byte
 | 
			
		|||
uninitialized_read_large
 | 
			
		||||
uninitialized_read_small
 | 
			
		||||
realloc_init
 | 
			
		||||
memcpy_buffer_overflow
 | 
			
		||||
memcpy_read_overflow
 | 
			
		||||
memcpy_valid_same
 | 
			
		||||
memcpy_valid_mismatched
 | 
			
		||||
memmove_buffer_overflow
 | 
			
		||||
memmove_read_overflow
 | 
			
		||||
memmove_valid_same
 | 
			
		||||
memmove_valid_mismatched
 | 
			
		||||
memset_buffer_overflow
 | 
			
		||||
memset_valid_same
 | 
			
		||||
memset_valid_mismatched
 | 
			
		||||
__pycache__/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,7 +67,18 @@ EXECUTABLES := \
 | 
			
		|||
    invalid_malloc_object_size_small \
 | 
			
		||||
    invalid_malloc_object_size_small_quarantine \
 | 
			
		||||
    impossibly_large_malloc \
 | 
			
		||||
    realloc_init
 | 
			
		||||
    realloc_init \
 | 
			
		||||
    memcpy_buffer_overflow \
 | 
			
		||||
    memcpy_read_overflow \
 | 
			
		||||
    memcpy_valid_same \
 | 
			
		||||
    memcpy_valid_mismatched \
 | 
			
		||||
    memmove_buffer_overflow \
 | 
			
		||||
    memmove_read_overflow \
 | 
			
		||||
    memmove_valid_same \
 | 
			
		||||
    memmove_valid_mismatched \
 | 
			
		||||
    memset_buffer_overflow \
 | 
			
		||||
    memset_valid_same \
 | 
			
		||||
    memset_valid_mismatched
 | 
			
		||||
 | 
			
		||||
all: $(EXECUTABLES)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								test/memcpy_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memcpy_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *firstbuffer = malloc(16);
 | 
			
		||||
    char *secondbuffer = malloc(32);
 | 
			
		||||
    if (!firstbuffer && !secondbuffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(secondbuffer, 'a', 32);
 | 
			
		||||
    memcpy(firstbuffer, secondbuffer, 32);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								test/memcpy_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memcpy_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *firstbuffer = malloc(32);
 | 
			
		||||
    char *secondbuffer = malloc(16);
 | 
			
		||||
    if (!firstbuffer && !secondbuffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(secondbuffer, 'a', 16);
 | 
			
		||||
    memcpy(firstbuffer, secondbuffer, 32);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								test/memcpy_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memcpy_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *firstbuffer = malloc(32);
 | 
			
		||||
    char *secondbuffer = malloc(16);
 | 
			
		||||
    if (!firstbuffer && !secondbuffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(secondbuffer, 'a', 16);
 | 
			
		||||
    memcpy(firstbuffer, secondbuffer, 16);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								test/memcpy_valid_same.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memcpy_valid_same.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *firstbuffer = malloc(16);
 | 
			
		||||
    char *secondbuffer = malloc(16);
 | 
			
		||||
    if (!firstbuffer && !secondbuffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(secondbuffer, 'a', 16);
 | 
			
		||||
    memcpy(firstbuffer, secondbuffer, 16);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								test/memmove_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memmove_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *firstbuffer = malloc(16);
 | 
			
		||||
    char *secondbuffer = malloc(32);
 | 
			
		||||
    if (!firstbuffer && !secondbuffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(secondbuffer, 'a', 32);
 | 
			
		||||
    memmove(firstbuffer, secondbuffer, 32);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								test/memmove_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memmove_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *firstbuffer = malloc(32);
 | 
			
		||||
    char *secondbuffer = malloc(16);
 | 
			
		||||
    if (!firstbuffer && !secondbuffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(secondbuffer, 'a', 16);
 | 
			
		||||
    memmove(firstbuffer, secondbuffer, 32);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								test/memmove_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memmove_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *firstbuffer = malloc(32);
 | 
			
		||||
    char *secondbuffer = malloc(16);
 | 
			
		||||
    if (!firstbuffer && !secondbuffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(secondbuffer, 'a', 16);
 | 
			
		||||
    memmove(firstbuffer, secondbuffer, 16);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								test/memmove_valid_same.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memmove_valid_same.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *firstbuffer = malloc(16);
 | 
			
		||||
    char *secondbuffer = malloc(16);
 | 
			
		||||
    if (!firstbuffer && !secondbuffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(secondbuffer, 'a', 16);
 | 
			
		||||
    memmove(firstbuffer, secondbuffer, 16);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								test/memset_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/memset_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *buffer = malloc(16);
 | 
			
		||||
    if (!buffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(buffer, 'a', 32);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								test/memset_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/memset_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *buffer = malloc(32);
 | 
			
		||||
    if (!buffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(buffer, 'a', 16);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										13
									
								
								test/memset_valid_same.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/memset_valid_same.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "test_util.h"
 | 
			
		||||
 | 
			
		||||
OPTNONE int main(void) {
 | 
			
		||||
    char *buffer = malloc(16);
 | 
			
		||||
    if (!buffer) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    memset(buffer, 'a', 16);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -238,5 +238,70 @@ class TestSimpleMemoryCorruption(unittest.TestCase):
 | 
			
		|||
            "realloc_init")
 | 
			
		||||
        self.assertEqual(returncode, 0)
 | 
			
		||||
 | 
			
		||||
    #def test_memcpy_buffer_overflow(self):
 | 
			
		||||
    #    _stdout, stderr, returncode = self.run_test(
 | 
			
		||||
    #        "memcpy_buffer_overflow")
 | 
			
		||||
    #    self.assertEqual(returncode, -6)
 | 
			
		||||
    #    self.assertEqual(stderr.decode(
 | 
			
		||||
    #        "utf-8"), "fatal allocator error: memcpy buffer overflow\n")
 | 
			
		||||
 | 
			
		||||
    #def test_memcpy_read_overflow(self):
 | 
			
		||||
    #    _stdout, stderr, returncode = self.run_test(
 | 
			
		||||
    #        "memcpy_read_overflow")
 | 
			
		||||
    #    self.assertEqual(returncode, -6)
 | 
			
		||||
    #    self.assertEqual(stderr.decode(
 | 
			
		||||
    #        "utf-8"), "fatal allocator error: memcpy read overflow\n")
 | 
			
		||||
 | 
			
		||||
    def test_memcpy_valid_same(self):
 | 
			
		||||
        _stdout, _stderr, returncode = self.run_test(
 | 
			
		||||
            "memcpy_valid_same")
 | 
			
		||||
        self.assertEqual(returncode, 0)
 | 
			
		||||
 | 
			
		||||
    def test_memcpy_valid_mismatched(self):
 | 
			
		||||
        _stdout, _stderr, returncode = self.run_test(
 | 
			
		||||
            "memcpy_valid_mismatched")
 | 
			
		||||
        self.assertEqual(returncode, 0)
 | 
			
		||||
 | 
			
		||||
    #def test_memmove_buffer_overflow(self):
 | 
			
		||||
    #    _stdout, stderr, returncode = self.run_test(
 | 
			
		||||
    #        "memmove_buffer_overflow")
 | 
			
		||||
    #    self.assertEqual(returncode, -6)
 | 
			
		||||
    #    self.assertEqual(stderr.decode(
 | 
			
		||||
    #        "utf-8"), "fatal allocator error: memmove buffer overflow\n")
 | 
			
		||||
 | 
			
		||||
    #def test_memmove_read_overflow(self):
 | 
			
		||||
    #    _stdout, stderr, returncode = self.run_test(
 | 
			
		||||
    #        "memmove_read_overflow")
 | 
			
		||||
    #    self.assertEqual(returncode, -6)
 | 
			
		||||
    #    self.assertEqual(stderr.decode(
 | 
			
		||||
    #        "utf-8"), "fatal allocator error: memmove read overflow\n")
 | 
			
		||||
 | 
			
		||||
    def test_memmove_valid_same(self):
 | 
			
		||||
        _stdout, _stderr, returncode = self.run_test(
 | 
			
		||||
            "memmove_valid_same")
 | 
			
		||||
        self.assertEqual(returncode, 0)
 | 
			
		||||
 | 
			
		||||
    def test_memmove_valid_mismatched(self):
 | 
			
		||||
        _stdout, _stderr, returncode = self.run_test(
 | 
			
		||||
            "memmove_valid_mismatched")
 | 
			
		||||
        self.assertEqual(returncode, 0)
 | 
			
		||||
 | 
			
		||||
    #def test_memset_buffer_overflow(self):
 | 
			
		||||
    #    _stdout, stderr, returncode = self.run_test(
 | 
			
		||||
    #        "memset_buffer_overflow")
 | 
			
		||||
    #    self.assertEqual(returncode, -6)
 | 
			
		||||
    #    self.assertEqual(stderr.decode(
 | 
			
		||||
    #        "utf-8"), "fatal allocator error: memset buffer overflow\n")
 | 
			
		||||
 | 
			
		||||
    def test_memset_valid_same(self):
 | 
			
		||||
        _stdout, _stderr, returncode = self.run_test(
 | 
			
		||||
            "memset_valid_same")
 | 
			
		||||
        self.assertEqual(returncode, 0)
 | 
			
		||||
 | 
			
		||||
    def test_memset_valid_mismatched(self):
 | 
			
		||||
        _stdout, _stderr, returncode = self.run_test(
 | 
			
		||||
            "memset_valid_mismatched")
 | 
			
		||||
        self.assertEqual(returncode, 0)
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    unittest.main()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue