mirror of
https://github.com/GrapheneOS/hardened_malloc.git
synced 2025-04-19 22:10:19 +02:00
perform size checks on memcpy/memmove/memset
Signed-off-by: Tavi <tavi@divested.dev>
This commit is contained in:
parent
4fe9018b6f
commit
c0b4033769
21 changed files with 412 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 {
|
||||
|
|
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
|
||||
|
|
129
h_malloc.c
129
h_malloc.c
|
@ -19,6 +19,7 @@
|
|||
#include "pages.h"
|
||||
#include "random.h"
|
||||
#include "util.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef USE_PKEY
|
||||
#include <sys/mman.h>
|
||||
|
@ -528,7 +529,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 +542,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 +832,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 +1503,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 +1625,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 +1647,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 +1875,122 @@ EXPORT size_t h_malloc_object_size_fast(const void *p) {
|
|||
return SIZE_MAX;
|
||||
}
|
||||
|
||||
#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
|
||||
FILE *(*original_memcpy)(void *restrict, const void *restrict, size_t);
|
||||
inline void *h_memcpy_real(void *restrict dst, const void *restrict src, size_t len) {
|
||||
if(!original_memcpy) original_memcpy = dlsym(RTLD_NEXT, "memcpy");
|
||||
return (*original_memcpy)(dst, src, len);
|
||||
}
|
||||
|
||||
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_real(dst, src, len);
|
||||
}
|
||||
|
||||
FILE *(*original_memmove)(void *, const void *, size_t);
|
||||
inline void *h_memmove_real(void *dst, const void *src, size_t len) {
|
||||
if(!original_memmove) original_memmove = dlsym(RTLD_NEXT, "memmove");
|
||||
return (*original_memmove)(dst, src, len);
|
||||
}
|
||||
|
||||
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_real(dst, src, len);
|
||||
}
|
||||
|
||||
FILE *(*original_memset)(void *, int, size_t);
|
||||
inline void *h_memset_real(void *dst, int value, size_t len) {
|
||||
if(!original_memset) original_memset = dlsym(RTLD_NEXT, "memset");
|
||||
return (*original_memset)(dst, value, len);
|
||||
}
|
||||
|
||||
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_real(dst, value, len);
|
||||
}
|
||||
|
||||
wchar_t *(*original_wmemcpy)(wchar_t *restrict, const wchar_t *restrict, size_t);
|
||||
inline wchar_t *h_wmemcpy_real(wchar_t *restrict dst, const wchar_t *restrict src, size_t len) {
|
||||
if(!original_wmemcpy) original_wmemcpy = dlsym(RTLD_NEXT, "wmemcpy");
|
||||
return (*original_wmemcpy)(dst, src, len);
|
||||
}
|
||||
|
||||
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_real(dst, src, len);
|
||||
}
|
||||
|
||||
wchar_t *(*original_wmemmove)(wchar_t *, const wchar_t *, size_t);
|
||||
inline wchar_t *h_wmemmove_real(wchar_t *dst, const wchar_t *src, size_t len) {
|
||||
if(!original_wmemmove) original_wmemmove = dlsym(RTLD_NEXT, "wmemmove");
|
||||
return (*original_wmemmove)(dst, src, len);
|
||||
}
|
||||
|
||||
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_real(dst, src, len);
|
||||
}
|
||||
|
||||
wchar_t *(*original_wmemset)(wchar_t *, wchar_t, size_t);
|
||||
inline wchar_t *h_wmemset_real(wchar_t *dst, wchar_t value, size_t len) {
|
||||
if(!original_wmemset) original_wmemset = dlsym(RTLD_NEXT, "wmemset");
|
||||
return (*original_wmemset)(dst, value, len);
|
||||
}
|
||||
|
||||
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_real(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
|
||||
|
||||
|
@ -55,6 +63,28 @@ __attribute__((malloc)) __attribute__((alloc_size(2))) __attribute__((alloc_alig
|
|||
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)
|
||||
void *h_memcpy_real(void *dst, const void *src, size_t len);
|
||||
void *h_memcpy_wrapped(void *dst, const void *src, size_t len);
|
||||
void *h_memmove_real(void *dst, const void *src, size_t len);
|
||||
void *h_memmove_wrapped(void *dst, const void *src, size_t len);
|
||||
void *h_memset_real(void *dst, int value, size_t len);
|
||||
void *h_memset_wrapped(void *dst, int value, size_t len);
|
||||
wchar_t *h_wmemcpy_real(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_real(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_real(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_real
|
||||
#define h_memove_internal h_memmove_real
|
||||
#define h_memset_internal h_memset_real
|
||||
#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