mirror of
				https://github.com/GrapheneOS/hardened_malloc.git
				synced 2025-11-04 01:36:33 +01:00 
			
		
		
		
	Compare commits
	
		
			2 commits
		
	
	
		
			d5ee81e0c4
			...
			778914e562
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							 | 
						778914e562 | ||
| 
							 | 
						2f06cddeb7 | 
					 46 changed files with 1166 additions and 13 deletions
				
			
		| 
						 | 
					@ -28,6 +28,7 @@ common_cflags = [
 | 
				
			||||||
    "-DN_ARENA=1",
 | 
					    "-DN_ARENA=1",
 | 
				
			||||||
    "-DCONFIG_STATS=true",
 | 
					    "-DCONFIG_STATS=true",
 | 
				
			||||||
    "-DCONFIG_SELF_INIT=false",
 | 
					    "-DCONFIG_SELF_INIT=false",
 | 
				
			||||||
 | 
					    "-DCONFIG_BLOCK_OPS_CHECK_SIZE=false",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cc_defaults {
 | 
					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
 | 
					    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
				
			||||||
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
					    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					memcpy.c, memccpy.c, memmove.c, memset.c, swab.c, wmemset.c:
 | 
				
			||||||
 | 
					    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:
 | 
					libdivide:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Copyright (C) 2010 - 2019 ridiculous_fish, <libdivide@ridiculousfish.com>
 | 
					    Copyright (C) 2010 - 2019 ridiculous_fish, <libdivide@ridiculousfish.com>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										28
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -40,6 +40,10 @@ CXXFLAGS := $(CXXFLAGS) -std=c++17 -fsized-deallocation $(SHARED_FLAGS)
 | 
				
			||||||
LDFLAGS := $(LDFLAGS) -Wl,-O1,--as-needed,-z,defs,-z,relro,-z,now,-z,nodlopen,-z,text
 | 
					LDFLAGS := $(LDFLAGS) -Wl,-O1,--as-needed,-z,defs,-z,relro,-z,now,-z,nodlopen,-z,text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SOURCES := chacha.c h_malloc.c memory.c pages.c random.c util.c
 | 
					SOURCES := chacha.c h_malloc.c memory.c pages.c random.c util.c
 | 
				
			||||||
 | 
					ifeq ($(CONFIG_BLOCK_OPS_CHECK_SIZE),true)
 | 
				
			||||||
 | 
					    SOURCES += memcpy.c memccpy.c memmove.c memset.c swab.c wmemset.c
 | 
				
			||||||
 | 
					    BOSC_EXTRAS := musl.h
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
OBJECTS := $(SOURCES:.c=.o)
 | 
					OBJECTS := $(SOURCES:.c=.o)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(CONFIG_CXX_ALLOCATOR),true)
 | 
					ifeq ($(CONFIG_CXX_ALLOCATOR),true)
 | 
				
			||||||
| 
						 | 
					@ -89,6 +93,10 @@ ifeq (,$(filter $(CONFIG_SELF_INIT),true false))
 | 
				
			||||||
    $(error CONFIG_SELF_INIT must be true or false)
 | 
					    $(error CONFIG_SELF_INIT must be true or false)
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifeq (,$(filter $(CONFIG_BLOCK_OPS_CHECK_SIZE),true false))
 | 
				
			||||||
 | 
					    $(error CONFIG_BLOCK_OPS_CHECK_SIZE must be true or false)
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CPPFLAGS += \
 | 
					CPPFLAGS += \
 | 
				
			||||||
    -DCONFIG_SEAL_METADATA=$(CONFIG_SEAL_METADATA) \
 | 
					    -DCONFIG_SEAL_METADATA=$(CONFIG_SEAL_METADATA) \
 | 
				
			||||||
    -DZERO_ON_FREE=$(CONFIG_ZERO_ON_FREE) \
 | 
					    -DZERO_ON_FREE=$(CONFIG_ZERO_ON_FREE) \
 | 
				
			||||||
| 
						 | 
					@ -108,7 +116,8 @@ CPPFLAGS += \
 | 
				
			||||||
    -DCONFIG_CLASS_REGION_SIZE=$(CONFIG_CLASS_REGION_SIZE) \
 | 
					    -DCONFIG_CLASS_REGION_SIZE=$(CONFIG_CLASS_REGION_SIZE) \
 | 
				
			||||||
    -DN_ARENA=$(CONFIG_N_ARENA) \
 | 
					    -DN_ARENA=$(CONFIG_N_ARENA) \
 | 
				
			||||||
    -DCONFIG_STATS=$(CONFIG_STATS) \
 | 
					    -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)
 | 
					$(OUT)/libhardened_malloc$(SUFFIX).so: $(OBJECTS) | $(OUT)
 | 
				
			||||||
	$(CC) $(CFLAGS) $(LDFLAGS) -shared $^ $(LDLIBS) -o $@
 | 
						$(CC) $(CFLAGS) $(LDFLAGS) -shared $^ $(LDLIBS) -o $@
 | 
				
			||||||
| 
						 | 
					@ -118,7 +127,7 @@ $(OUT):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(OUT)/chacha.o: chacha.c chacha.h util.h $(CONFIG_FILE) | $(OUT)
 | 
					$(OUT)/chacha.o: chacha.c chacha.h util.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
	$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
						$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
				
			||||||
$(OUT)/h_malloc.o: h_malloc.c include/h_malloc.h mutex.h memory.h pages.h random.h util.h $(CONFIG_FILE) | $(OUT)
 | 
					$(OUT)/h_malloc.o: h_malloc.c include/h_malloc.h mutex.h memory.h $(BOSC_EXTRAS) pages.h random.h util.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
	$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
						$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
				
			||||||
$(OUT)/memory.o: memory.c memory.h util.h $(CONFIG_FILE) | $(OUT)
 | 
					$(OUT)/memory.o: memory.c memory.h util.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
	$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
						$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
				
			||||||
| 
						 | 
					@ -126,11 +135,24 @@ $(OUT)/new.o: new.cc include/h_malloc.h util.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
	$(COMPILE.cc) $(OUTPUT_OPTION) $<
 | 
						$(COMPILE.cc) $(OUTPUT_OPTION) $<
 | 
				
			||||||
$(OUT)/pages.o: pages.c pages.h memory.h util.h $(CONFIG_FILE) | $(OUT)
 | 
					$(OUT)/pages.o: pages.c pages.h memory.h util.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
	$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
						$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
				
			||||||
$(OUT)/random.o: random.c random.h chacha.h util.h $(CONFIG_FILE) | $(OUT)
 | 
					$(OUT)/random.o: random.c random.h chacha.h $(BOSC_EXTRAS) util.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
	$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
						$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
				
			||||||
$(OUT)/util.o: util.c util.h $(CONFIG_FILE) | $(OUT)
 | 
					$(OUT)/util.o: util.c util.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
	$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
						$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(OUT)/memcpy.o: memcpy.c musl.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
 | 
						$(COMPILE.c) -Wno-cast-align $(OUTPUT_OPTION) $<
 | 
				
			||||||
 | 
					$(OUT)/memccpy.o: memccpy.c musl.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
 | 
						$(COMPILE.c) -Wno-cast-align $(OUTPUT_OPTION) $<
 | 
				
			||||||
 | 
					$(OUT)/memmove.o: memmove.c musl.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
 | 
						$(COMPILE.c) -Wno-cast-align $(OUTPUT_OPTION) $<
 | 
				
			||||||
 | 
					$(OUT)/memset.o: memset.c musl.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
 | 
						$(COMPILE.c) -Wno-cast-align $(OUTPUT_OPTION) $<
 | 
				
			||||||
 | 
					$(OUT)/swab.o: swab.c musl.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
 | 
						$(COMPILE.c) -Wno-cast-align $(OUTPUT_OPTION) $<
 | 
				
			||||||
 | 
					$(OUT)/wmemset.o: wmemset.c musl.h $(CONFIG_FILE) | $(OUT)
 | 
				
			||||||
 | 
						$(COMPILE.c) $(OUTPUT_OPTION) $<
 | 
				
			||||||
 | 
					
 | 
				
			||||||
check: tidy
 | 
					check: tidy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tidy:
 | 
					tidy:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -279,6 +279,9 @@ The following boolean configuration options are available:
 | 
				
			||||||
  hardware, which may become drastically lower in the future. Whether or not
 | 
					  hardware, which may become drastically lower in the future. Whether or not
 | 
				
			||||||
  this feature is enabled, the metadata is all contained within an isolated
 | 
					  this feature is enabled, the metadata is all contained within an isolated
 | 
				
			||||||
  memory region with high entropy random guard regions around it.
 | 
					  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/memccpy/memmove/memset block operations and their
 | 
				
			||||||
 | 
					  wide variants are within approximate bounds to minimize buffer overflows.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The following integer configuration options are available:
 | 
					The following integer configuration options are available:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,3 +21,4 @@ CONFIG_CLASS_REGION_SIZE := 34359738368 # 32GiB
 | 
				
			||||||
CONFIG_N_ARENA := 4
 | 
					CONFIG_N_ARENA := 4
 | 
				
			||||||
CONFIG_STATS := false
 | 
					CONFIG_STATS := false
 | 
				
			||||||
CONFIG_SELF_INIT := true
 | 
					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_N_ARENA := 4
 | 
				
			||||||
CONFIG_STATS := false
 | 
					CONFIG_STATS := false
 | 
				
			||||||
CONFIG_SELF_INIT := true
 | 
					CONFIG_SELF_INIT := true
 | 
				
			||||||
 | 
					CONFIG_BLOCK_OPS_CHECK_SIZE := false
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										143
									
								
								h_malloc.c
									
										
									
									
									
								
							
							
						
						
									
										143
									
								
								h_malloc.c
									
										
									
									
									
								
							| 
						 | 
					@ -20,6 +20,10 @@
 | 
				
			||||||
#include "random.h"
 | 
					#include "random.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
 | 
				
			||||||
 | 
					#include "musl.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_PKEY
 | 
					#ifdef USE_PKEY
 | 
				
			||||||
#include <sys/mman.h>
 | 
					#include <sys/mman.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -528,7 +532,7 @@ static void set_canary(UNUSED const struct slab_metadata *metadata, UNUSED void
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#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
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -541,7 +545,7 @@ static void check_canary(UNUSED const struct slab_metadata *metadata, UNUSED con
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u64 canary_value;
 | 
					    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
 | 
					#ifdef HAS_ARM_MTE
 | 
				
			||||||
    if (unlikely(canary_value == 0)) {
 | 
					    if (unlikely(canary_value == 0)) {
 | 
				
			||||||
| 
						 | 
					@ -831,7 +835,7 @@ static inline void deallocate_small(void *p, const size_t *expected_size) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (ZERO_ON_FREE && !skip_zero) {
 | 
					        if (ZERO_ON_FREE && !skip_zero) {
 | 
				
			||||||
            memset(p, 0, size - canary_size);
 | 
					            h_memset_internal(p, 0, size - canary_size);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1502,7 +1506,7 @@ EXPORT void *h_calloc(size_t nmemb, size_t size) {
 | 
				
			||||||
    total_size = adjust_size_for_canary(total_size);
 | 
					    total_size = adjust_size_for_canary(total_size);
 | 
				
			||||||
    void *p = alloc(total_size);
 | 
					    void *p = alloc(total_size);
 | 
				
			||||||
    if (!ZERO_ON_FREE && likely(p != NULL) && total_size && total_size <= max_slab_size_class) {
 | 
					    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
 | 
					#ifdef HAS_ARM_MTE
 | 
				
			||||||
    // use an assert instead of adding a conditional to memset() above (freed memory is always
 | 
					    // use an assert instead of adding a conditional to memset() above (freed memory is always
 | 
				
			||||||
| 
						 | 
					@ -1624,7 +1628,7 @@ EXPORT void *h_realloc(void *old, size_t size) {
 | 
				
			||||||
                mutex_unlock(&ra->lock);
 | 
					                mutex_unlock(&ra->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (memory_remap_fixed(old, old_size, new, size)) {
 | 
					                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);
 | 
					                    deallocate_pages(old, old_size, old_guard_size);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    memory_unmap((char *)old - old_guard_size, old_guard_size);
 | 
					                    memory_unmap((char *)old - old_guard_size, old_guard_size);
 | 
				
			||||||
| 
						 | 
					@ -1646,7 +1650,7 @@ EXPORT void *h_realloc(void *old, size_t size) {
 | 
				
			||||||
    if (copy_size > 0 && copy_size <= max_slab_size_class) {
 | 
					    if (copy_size > 0 && copy_size <= max_slab_size_class) {
 | 
				
			||||||
        copy_size -= canary_size;
 | 
					        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) {
 | 
					    if (old_size <= max_slab_size_class) {
 | 
				
			||||||
        deallocate_small(old, NULL);
 | 
					        deallocate_small(old, NULL);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
| 
						 | 
					@ -1874,6 +1878,133 @@ EXPORT size_t h_malloc_object_size_fast(const void *p) {
 | 
				
			||||||
    return SIZE_MAX;
 | 
					    return SIZE_MAX;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
 | 
				
			||||||
 | 
					EXPORT void *memcpy(void *restrict dst, const void *restrict src, size_t len) {
 | 
				
			||||||
 | 
					    if (unlikely(dst == src || len == 0)) {
 | 
				
			||||||
 | 
					        return dst;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(dst < (src + len) && (dst + len) > src)) {
 | 
				
			||||||
 | 
					        fatal_error("memcpy overlap");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(len > malloc_object_size(src))) {
 | 
				
			||||||
 | 
					        fatal_error("memcpy read overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(len > malloc_object_size(dst))) {
 | 
				
			||||||
 | 
					        fatal_error("memcpy buffer overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return musl_memcpy(dst, src, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT void *memccpy(void *restrict dst, const void *restrict src, int value, size_t len) {
 | 
				
			||||||
 | 
					    if (unlikely(dst == src || len == 0)) {
 | 
				
			||||||
 | 
					        return dst;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(dst < (src + len) && (dst + len) > src)) {
 | 
				
			||||||
 | 
					        fatal_error("memccpy overlap");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(len > malloc_object_size(src) && value != 0)) {
 | 
				
			||||||
 | 
					        fatal_error("memccpy read overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(len > malloc_object_size(dst))) {
 | 
				
			||||||
 | 
					        fatal_error("memccpy buffer overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return musl_memccpy(dst, src, value, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT void *memmove(void *dst, const void *src, size_t len) {
 | 
				
			||||||
 | 
					    if (unlikely(dst == src || len == 0)) {
 | 
				
			||||||
 | 
					        return dst;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(len > malloc_object_size(src))) {
 | 
				
			||||||
 | 
					        fatal_error("memmove read overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(len > malloc_object_size(dst))) {
 | 
				
			||||||
 | 
					        fatal_error("memmove buffer overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return musl_memmove(dst, src, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT void *mempcpy(void *restrict dst, const void *restrict src, size_t len) {
 | 
				
			||||||
 | 
					    return memcpy(dst, src, len) + len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT void *memset(void *dst, int value, size_t len) {
 | 
				
			||||||
 | 
					    if (unlikely(len == 0)) {
 | 
				
			||||||
 | 
					        return dst;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(len > malloc_object_size(dst))) {
 | 
				
			||||||
 | 
					        fatal_error("memset buffer overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return musl_memset(dst, value, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT void bcopy(const void *src, void *dst, size_t len) {
 | 
				
			||||||
 | 
					    memmove(dst, src, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT void swab(const void *restrict src, void *restrict dst, ssize_t len) {
 | 
				
			||||||
 | 
					    if (unlikely(len <= 0)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    size_t length = len;
 | 
				
			||||||
 | 
					    if (unlikely(dst < (src + length) && (dst + length) > src)) {
 | 
				
			||||||
 | 
					        fatal_error("swab overlap");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(length > malloc_object_size(src))) {
 | 
				
			||||||
 | 
					        fatal_error("swab read overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(length > malloc_object_size(dst))) {
 | 
				
			||||||
 | 
					        fatal_error("swab buffer overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return musl_swab(src, dst, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT wchar_t *wmemcpy(wchar_t *restrict dst, const wchar_t *restrict src, size_t len) {
 | 
				
			||||||
 | 
					    if (unlikely(dst == src || len == 0)) {
 | 
				
			||||||
 | 
					        return dst;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(dst < (src + len) && (dst + len) > src)) {
 | 
				
			||||||
 | 
					        fatal_error("wmemcpy overlap");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    size_t lenAdj = len * sizeof(wchar_t);
 | 
				
			||||||
 | 
					    if (unlikely(lenAdj > malloc_object_size(src))) {
 | 
				
			||||||
 | 
					        fatal_error("wmemcpy read overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(lenAdj > malloc_object_size(dst))) {
 | 
				
			||||||
 | 
					        fatal_error("wmemcpy buffer overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (wchar_t *)musl_memcpy((char *)dst, (const char *)src, lenAdj);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT wchar_t *wmemmove(wchar_t *dst, const wchar_t *src, size_t len) {
 | 
				
			||||||
 | 
					    if (unlikely(dst == src || len == 0)) {
 | 
				
			||||||
 | 
					        return dst;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    size_t lenAdj = len * sizeof(wchar_t);
 | 
				
			||||||
 | 
					    if (unlikely(lenAdj > malloc_object_size(src))) {
 | 
				
			||||||
 | 
					        fatal_error("wmemmove read overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely(lenAdj > malloc_object_size(dst))) {
 | 
				
			||||||
 | 
					        fatal_error("wmemmove buffer overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (wchar_t *)musl_memmove((char *)dst, (const char *)src, lenAdj);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT wchar_t *wmempcpy(wchar_t *restrict dst, const wchar_t *restrict src, size_t len) {
 | 
				
			||||||
 | 
					    return wmemcpy(dst, src, len) + len;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXPORT wchar_t *wmemset(wchar_t *dst, wchar_t value, size_t len) {
 | 
				
			||||||
 | 
					    if (unlikely(len == 0)) {
 | 
				
			||||||
 | 
					        return dst;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (unlikely((len * sizeof(wchar_t)) > malloc_object_size(dst))) {
 | 
				
			||||||
 | 
					        fatal_error("wmemset buffer overflow");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return musl_wmemset(dst, value, len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif /* CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPORT int h_mallopt(UNUSED int param, UNUSED int value) {
 | 
					EXPORT int h_mallopt(UNUSED int param, UNUSED int value) {
 | 
				
			||||||
#ifdef __ANDROID__
 | 
					#ifdef __ANDROID__
 | 
				
			||||||
    if (param == M_PURGE) {
 | 
					    if (param == M_PURGE) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,27 @@ __attribute__((malloc)) __attribute__((alloc_size(2))) __attribute__((alloc_alig
 | 
				
			||||||
void *h_aligned_alloc(size_t alignment, size_t size);
 | 
					void *h_aligned_alloc(size_t alignment, size_t size);
 | 
				
			||||||
void h_free(void *ptr);
 | 
					void h_free(void *ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
 | 
				
			||||||
 | 
					void *memcpy(void *dst, const void *src, size_t len);
 | 
				
			||||||
 | 
					void *memccpy(void *dst, const void *src, int value, size_t len);
 | 
				
			||||||
 | 
					void *memmove(void *dst, const void *src, size_t len);
 | 
				
			||||||
 | 
					void *mempcpy(void *dst, const void *src, size_t len);
 | 
				
			||||||
 | 
					void *memset(void *dst, int value, size_t len);
 | 
				
			||||||
 | 
					void bcopy(const void *src, void *dst, size_t len);
 | 
				
			||||||
 | 
					void swab(const void *src, void *dst, ssize_t len);
 | 
				
			||||||
 | 
					wchar_t *wmemcpy(wchar_t *dst, const wchar_t *src, size_t len);
 | 
				
			||||||
 | 
					wchar_t *wmemmove(wchar_t *dst, const wchar_t *src, size_t len);
 | 
				
			||||||
 | 
					wchar_t *wmempcpy(wchar_t *dst, const wchar_t *src, size_t len);
 | 
				
			||||||
 | 
					wchar_t *wmemset(wchar_t *dst, wchar_t value, size_t len);
 | 
				
			||||||
 | 
					#define h_memcpy_internal musl_memcpy
 | 
				
			||||||
 | 
					#define h_memmove_internal musl_memmove
 | 
				
			||||||
 | 
					#define h_memset_internal musl_memset
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define h_memcpy_internal memcpy
 | 
				
			||||||
 | 
					#define h_memmove_internal memmove
 | 
				
			||||||
 | 
					#define h_memset_internal memset
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// POSIX
 | 
					// POSIX
 | 
				
			||||||
int h_posix_memalign(void **memptr, size_t alignment, size_t size);
 | 
					int h_posix_memalign(void **memptr, size_t alignment, size_t size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										38
									
								
								memccpy.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								memccpy.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					#include "musl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Copied from musl libc version 1.2.5 licensed under the MIT license */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <limits.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALIGN (sizeof(size_t)-1)
 | 
				
			||||||
 | 
					#define ONES ((size_t)-1/UCHAR_MAX)
 | 
				
			||||||
 | 
					#define HIGHS (ONES * (UCHAR_MAX/2+1))
 | 
				
			||||||
 | 
					#define HASZERO(x) (((x)-ONES) & ~(x) & HIGHS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *musl_memccpy(void *restrict dest, const void *restrict src, int c, size_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned char *d = dest;
 | 
				
			||||||
 | 
						const unsigned char *s = src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c = (unsigned char)c;
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
						typedef size_t __attribute__((__may_alias__)) word;
 | 
				
			||||||
 | 
						word *wd;
 | 
				
			||||||
 | 
						const word *ws;
 | 
				
			||||||
 | 
						if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
 | 
				
			||||||
 | 
							for (; ((uintptr_t)s & ALIGN) && n && (*d=*s)!=c; n--, s++, d++);
 | 
				
			||||||
 | 
							if ((uintptr_t)s & ALIGN) goto tail;
 | 
				
			||||||
 | 
							size_t k = ONES * c;
 | 
				
			||||||
 | 
							wd=(void *)d; ws=(const void *)s;
 | 
				
			||||||
 | 
							for (; n>=sizeof(size_t) && !HASZERO(*ws^k);
 | 
				
			||||||
 | 
							       n-=sizeof(size_t), ws++, wd++) *wd = *ws;
 | 
				
			||||||
 | 
							d=(void *)wd; s=(const void *)ws;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						for (; n && (*d=*s)!=c; n--, s++, d++);
 | 
				
			||||||
 | 
					tail:
 | 
				
			||||||
 | 
						if (n) return d+1;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										132
									
								
								memcpy.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								memcpy.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,132 @@
 | 
				
			||||||
 | 
					#include "musl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copied from musl libc version 1.2.5 licensed under the MIT license
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Christian Göttsche: Added const qualifiers to retain const correctness.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <endian.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *musl_memcpy(void *restrict dest, const void *restrict src, size_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned char *d = dest;
 | 
				
			||||||
 | 
						const unsigned char *s = src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __BYTE_ORDER == __LITTLE_ENDIAN
 | 
				
			||||||
 | 
					#define LS >>
 | 
				
			||||||
 | 
					#define RS <<
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define LS <<
 | 
				
			||||||
 | 
					#define RS >>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						typedef uint32_t __attribute__((__may_alias__)) u32;
 | 
				
			||||||
 | 
						uint32_t w, x;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ((uintptr_t)d % 4 == 0) {
 | 
				
			||||||
 | 
							for (; n>=16; s+=16, d+=16, n-=16) {
 | 
				
			||||||
 | 
								*(u32 *)(d+0) = *(const u32 *)(s+0);
 | 
				
			||||||
 | 
								*(u32 *)(d+4) = *(const u32 *)(s+4);
 | 
				
			||||||
 | 
								*(u32 *)(d+8) = *(const u32 *)(s+8);
 | 
				
			||||||
 | 
								*(u32 *)(d+12) = *(const u32 *)(s+12);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (n&8) {
 | 
				
			||||||
 | 
								*(u32 *)(d+0) = *(const u32 *)(s+0);
 | 
				
			||||||
 | 
								*(u32 *)(d+4) = *(const u32 *)(s+4);
 | 
				
			||||||
 | 
								d += 8; s += 8;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (n&4) {
 | 
				
			||||||
 | 
								*(u32 *)(d+0) = *(const u32 *)(s+0);
 | 
				
			||||||
 | 
								d += 4; s += 4;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (n&2) {
 | 
				
			||||||
 | 
								*d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (n&1) {
 | 
				
			||||||
 | 
								*d = *s;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return dest;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (n >= 32) switch ((uintptr_t)d % 4) {
 | 
				
			||||||
 | 
						case 1:
 | 
				
			||||||
 | 
							w = *(const u32 *)s;
 | 
				
			||||||
 | 
							*d++ = *s++;
 | 
				
			||||||
 | 
							*d++ = *s++;
 | 
				
			||||||
 | 
							*d++ = *s++;
 | 
				
			||||||
 | 
							n -= 3;
 | 
				
			||||||
 | 
							for (; n>=17; s+=16, d+=16, n-=16) {
 | 
				
			||||||
 | 
								x = *(const u32 *)(s+1);
 | 
				
			||||||
 | 
								*(u32 *)(d+0) = (w LS 24) | (x RS 8);
 | 
				
			||||||
 | 
								w = *(const u32 *)(s+5);
 | 
				
			||||||
 | 
								*(u32 *)(d+4) = (x LS 24) | (w RS 8);
 | 
				
			||||||
 | 
								x = *(const u32 *)(s+9);
 | 
				
			||||||
 | 
								*(u32 *)(d+8) = (w LS 24) | (x RS 8);
 | 
				
			||||||
 | 
								w = *(const u32 *)(s+13);
 | 
				
			||||||
 | 
								*(u32 *)(d+12) = (x LS 24) | (w RS 8);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 2:
 | 
				
			||||||
 | 
							w = *(const u32 *)s;
 | 
				
			||||||
 | 
							*d++ = *s++;
 | 
				
			||||||
 | 
							*d++ = *s++;
 | 
				
			||||||
 | 
							n -= 2;
 | 
				
			||||||
 | 
							for (; n>=18; s+=16, d+=16, n-=16) {
 | 
				
			||||||
 | 
								x = *(const u32 *)(s+2);
 | 
				
			||||||
 | 
								*(u32 *)(d+0) = (w LS 16) | (x RS 16);
 | 
				
			||||||
 | 
								w = *(const u32 *)(s+6);
 | 
				
			||||||
 | 
								*(u32 *)(d+4) = (x LS 16) | (w RS 16);
 | 
				
			||||||
 | 
								x = *(const u32 *)(s+10);
 | 
				
			||||||
 | 
								*(u32 *)(d+8) = (w LS 16) | (x RS 16);
 | 
				
			||||||
 | 
								w = *(const u32 *)(s+14);
 | 
				
			||||||
 | 
								*(u32 *)(d+12) = (x LS 16) | (w RS 16);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 3:
 | 
				
			||||||
 | 
							w = *(const u32 *)s;
 | 
				
			||||||
 | 
							*d++ = *s++;
 | 
				
			||||||
 | 
							n -= 1;
 | 
				
			||||||
 | 
							for (; n>=19; s+=16, d+=16, n-=16) {
 | 
				
			||||||
 | 
								x = *(const u32 *)(s+3);
 | 
				
			||||||
 | 
								*(u32 *)(d+0) = (w LS 8) | (x RS 24);
 | 
				
			||||||
 | 
								w = *(const u32 *)(s+7);
 | 
				
			||||||
 | 
								*(u32 *)(d+4) = (x LS 8) | (w RS 24);
 | 
				
			||||||
 | 
								x = *(const u32 *)(s+11);
 | 
				
			||||||
 | 
								*(u32 *)(d+8) = (w LS 8) | (x RS 24);
 | 
				
			||||||
 | 
								w = *(const u32 *)(s+15);
 | 
				
			||||||
 | 
								*(u32 *)(d+12) = (x LS 8) | (w RS 24);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (n&16) {
 | 
				
			||||||
 | 
							*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
							*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
							*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
							*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (n&8) {
 | 
				
			||||||
 | 
							*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
							*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (n&4) {
 | 
				
			||||||
 | 
							*d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (n&2) {
 | 
				
			||||||
 | 
							*d++ = *s++; *d++ = *s++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (n&1) {
 | 
				
			||||||
 | 
							*d = *s;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return dest;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (; n; n--) *d++ = *s++;
 | 
				
			||||||
 | 
						return dest;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										50
									
								
								memmove.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								memmove.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					#include "musl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copied from musl libc version 1.2.5 licensed under the MIT license
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Christian Göttsche: Added const qualifiers to retain const correctness.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
					typedef __attribute__((__may_alias__)) size_t WT;
 | 
				
			||||||
 | 
					#define WS (sizeof(WT))
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *musl_memmove(void *dest, const void *src, size_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *d = dest;
 | 
				
			||||||
 | 
						const char *s = src;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (d==s) return d;
 | 
				
			||||||
 | 
						if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return musl_memcpy(d, s, n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (d<s) {
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
							if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
 | 
				
			||||||
 | 
								while ((uintptr_t)d % WS) {
 | 
				
			||||||
 | 
									if (!n--) return dest;
 | 
				
			||||||
 | 
									*d++ = *s++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(const WT *)s;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							for (; n; n--) *d++ = *s++;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
							if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
 | 
				
			||||||
 | 
								while ((uintptr_t)(d+n) % WS) {
 | 
				
			||||||
 | 
									if (!n--) return dest;
 | 
				
			||||||
 | 
									d[n] = s[n];
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								while (n>=WS) n-=WS, *(WT *)(d+n) = *(const WT *)(s+n);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							while (n) n--, d[n] = s[n];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dest;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										94
									
								
								memset.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								memset.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,94 @@
 | 
				
			||||||
 | 
					#include "musl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Copied from musl libc version 1.2.5 licensed under the MIT license */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *musl_memset(void *dest, int c, size_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned char *s = dest;
 | 
				
			||||||
 | 
						size_t k;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fill head and tail with minimal branching. Each
 | 
				
			||||||
 | 
						 * conditional ensures that all the subsequently used
 | 
				
			||||||
 | 
						 * offsets are well-defined and in the dest region. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!n) return dest;
 | 
				
			||||||
 | 
						s[0] = c;
 | 
				
			||||||
 | 
						s[n-1] = c;
 | 
				
			||||||
 | 
						if (n <= 2) return dest;
 | 
				
			||||||
 | 
						s[1] = c;
 | 
				
			||||||
 | 
						s[2] = c;
 | 
				
			||||||
 | 
						s[n-2] = c;
 | 
				
			||||||
 | 
						s[n-3] = c;
 | 
				
			||||||
 | 
						if (n <= 6) return dest;
 | 
				
			||||||
 | 
						s[3] = c;
 | 
				
			||||||
 | 
						s[n-4] = c;
 | 
				
			||||||
 | 
						if (n <= 8) return dest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Advance pointer to align it at a 4-byte boundary,
 | 
				
			||||||
 | 
						 * and truncate n to a multiple of 4. The previous code
 | 
				
			||||||
 | 
						 * already took care of any head/tail that get cut off
 | 
				
			||||||
 | 
						 * by the alignment. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						k = -(uintptr_t)s & 3;
 | 
				
			||||||
 | 
						s += k;
 | 
				
			||||||
 | 
						n -= k;
 | 
				
			||||||
 | 
						n &= -4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __GNUC__
 | 
				
			||||||
 | 
						typedef uint32_t __attribute__((__may_alias__)) u32;
 | 
				
			||||||
 | 
						typedef uint64_t __attribute__((__may_alias__)) u64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u32 c32 = ((u32)-1)/255 * (unsigned char)c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* In preparation to copy 32 bytes at a time, aligned on
 | 
				
			||||||
 | 
						 * an 8-byte bounary, fill head/tail up to 28 bytes each.
 | 
				
			||||||
 | 
						 * As in the initial byte-based head/tail fill, each
 | 
				
			||||||
 | 
						 * conditional below ensures that the subsequent offsets
 | 
				
			||||||
 | 
						 * are valid (e.g. !(n<=24) implies n>=28). */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*(u32 *)(s+0) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+n-4) = c32;
 | 
				
			||||||
 | 
						if (n <= 8) return dest;
 | 
				
			||||||
 | 
						*(u32 *)(s+4) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+8) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+n-12) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+n-8) = c32;
 | 
				
			||||||
 | 
						if (n <= 24) return dest;
 | 
				
			||||||
 | 
						*(u32 *)(s+12) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+16) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+20) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+24) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+n-28) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+n-24) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+n-20) = c32;
 | 
				
			||||||
 | 
						*(u32 *)(s+n-16) = c32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Align to a multiple of 8 so we can fill 64 bits at a time,
 | 
				
			||||||
 | 
						 * and avoid writing the same bytes twice as much as is
 | 
				
			||||||
 | 
						 * practical without introducing additional branching. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						k = 24 + ((uintptr_t)s & 4);
 | 
				
			||||||
 | 
						s += k;
 | 
				
			||||||
 | 
						n -= k;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If this loop is reached, 28 tail bytes have already been
 | 
				
			||||||
 | 
						 * filled, so any remainder when n drops below 32 can be
 | 
				
			||||||
 | 
						 * safely ignored. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u64 c64 = c32 | ((u64)c32 << 32);
 | 
				
			||||||
 | 
						for (; n >= 32; n-=32, s+=32) {
 | 
				
			||||||
 | 
							*(u64 *)(s+0) = c64;
 | 
				
			||||||
 | 
							*(u64 *)(s+8) = c64;
 | 
				
			||||||
 | 
							*(u64 *)(s+16) = c64;
 | 
				
			||||||
 | 
							*(u64 *)(s+24) = c64;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						/* Pure C fallback with no aliasing violations. */
 | 
				
			||||||
 | 
						for (; n; n--, s++) *s = c;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dest;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								musl.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								musl.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *musl_memcpy(void *dst, const void *src, size_t len);
 | 
				
			||||||
 | 
					void *musl_memccpy(void *restrict dest, const void *restrict src, int c, size_t n);
 | 
				
			||||||
 | 
					void *musl_memmove(void *dst, const void *src, size_t len);
 | 
				
			||||||
 | 
					void *musl_memset(void *dst, int value, size_t len);
 | 
				
			||||||
 | 
					void musl_swab(const void *_src, void *_dest, ssize_t n);
 | 
				
			||||||
 | 
					wchar_t *musl_wmemset(wchar_t *dst, wchar_t value, size_t len);
 | 
				
			||||||
							
								
								
									
										10
									
								
								random.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								random.c
									
										
									
									
									
								
							| 
						 | 
					@ -5,6 +5,10 @@
 | 
				
			||||||
#include "random.h"
 | 
					#include "random.h"
 | 
				
			||||||
#include "util.h"
 | 
					#include "util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
 | 
				
			||||||
 | 
					#include "musl.h"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/random.h>
 | 
					#include <sys/random.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void get_random_seed(void *buf, size_t size) {
 | 
					static void get_random_seed(void *buf, size_t size) {
 | 
				
			||||||
| 
						 | 
					@ -65,7 +69,7 @@ void get_random_bytes(struct random_state *state, void *buf, size_t size) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        size_t remaining = RANDOM_CACHE_SIZE - state->index;
 | 
					        size_t remaining = RANDOM_CACHE_SIZE - state->index;
 | 
				
			||||||
        size_t copy_size = min(size, remaining);
 | 
					        size_t copy_size = min(size, remaining);
 | 
				
			||||||
        memcpy(buf, state->cache + state->index, copy_size);
 | 
					        h_memcpy_internal(buf, state->cache + state->index, copy_size);
 | 
				
			||||||
        state->index += copy_size;
 | 
					        state->index += copy_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        buf = (char *)buf + copy_size;
 | 
					        buf = (char *)buf + copy_size;
 | 
				
			||||||
| 
						 | 
					@ -79,7 +83,7 @@ u16 get_random_u16(struct random_state *state) {
 | 
				
			||||||
    if (remaining < sizeof(value)) {
 | 
					    if (remaining < sizeof(value)) {
 | 
				
			||||||
        refill(state);
 | 
					        refill(state);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    memcpy(&value, state->cache + state->index, sizeof(value));
 | 
					    h_memcpy_internal(&value, state->cache + state->index, sizeof(value));
 | 
				
			||||||
    state->index += sizeof(value);
 | 
					    state->index += sizeof(value);
 | 
				
			||||||
    return value;
 | 
					    return value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -106,7 +110,7 @@ u64 get_random_u64(struct random_state *state) {
 | 
				
			||||||
    if (remaining < sizeof(value)) {
 | 
					    if (remaining < sizeof(value)) {
 | 
				
			||||||
        refill(state);
 | 
					        refill(state);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    memcpy(&value, state->cache + state->index, sizeof(value));
 | 
					    h_memcpy_internal(&value, state->cache + state->index, sizeof(value));
 | 
				
			||||||
    state->index += sizeof(value);
 | 
					    state->index += sizeof(value);
 | 
				
			||||||
    return value;
 | 
					    return value;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								random.h
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								random.h
									
										
									
									
									
								
							| 
						 | 
					@ -22,4 +22,10 @@ u16 get_random_u16_uniform(struct random_state *state, u16 bound);
 | 
				
			||||||
u64 get_random_u64(struct random_state *state);
 | 
					u64 get_random_u64(struct random_state *state);
 | 
				
			||||||
u64 get_random_u64_uniform(struct random_state *state, u64 bound);
 | 
					u64 get_random_u64_uniform(struct random_state *state, u64 bound);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if CONFIG_BLOCK_OPS_CHECK_SIZE && !defined(HAS_ARM_MTE)
 | 
				
			||||||
 | 
					#define h_memcpy_internal musl_memcpy
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define h_memcpy_internal memcpy
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								swab.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								swab.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					#include "musl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Copied from musl libc version 1.2.5 licensed under the MIT license */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void musl_swab(const void *restrict _src, void *restrict _dest, ssize_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					       const char *src = _src;
 | 
				
			||||||
 | 
					       char *dest = _dest;
 | 
				
			||||||
 | 
					       for (; n>1; n-=2) {
 | 
				
			||||||
 | 
					               dest[0] = src[1];
 | 
				
			||||||
 | 
					               dest[1] = src[0];
 | 
				
			||||||
 | 
					               dest += 2;
 | 
				
			||||||
 | 
					               src += 2;
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								test/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								test/.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -41,4 +41,30 @@ overflow_small_8_byte
 | 
				
			||||||
uninitialized_read_large
 | 
					uninitialized_read_large
 | 
				
			||||||
uninitialized_read_small
 | 
					uninitialized_read_small
 | 
				
			||||||
realloc_init
 | 
					realloc_init
 | 
				
			||||||
 | 
					memcpy_buffer_overflow
 | 
				
			||||||
 | 
					memcpy_read_overflow
 | 
				
			||||||
 | 
					memcpy_valid_same
 | 
				
			||||||
 | 
					memcpy_valid_mismatched
 | 
				
			||||||
 | 
					memccpy_buffer_overflow
 | 
				
			||||||
 | 
					memccpy_read_overflow
 | 
				
			||||||
 | 
					memccpy_valid_same
 | 
				
			||||||
 | 
					memccpy_valid_mismatched
 | 
				
			||||||
 | 
					memmove_buffer_overflow
 | 
				
			||||||
 | 
					memmove_read_overflow
 | 
				
			||||||
 | 
					memmove_valid_same
 | 
				
			||||||
 | 
					memmove_valid_mismatched
 | 
				
			||||||
 | 
					memset_buffer_overflow
 | 
				
			||||||
 | 
					memset_valid_same
 | 
				
			||||||
 | 
					memset_valid_mismatched
 | 
				
			||||||
 | 
					wmemcpy_buffer_overflow
 | 
				
			||||||
 | 
					wmemcpy_read_overflow
 | 
				
			||||||
 | 
					wmemcpy_valid_same
 | 
				
			||||||
 | 
					wmemcpy_valid_mismatched
 | 
				
			||||||
 | 
					wmemmove_buffer_overflow
 | 
				
			||||||
 | 
					wmemmove_read_overflow
 | 
				
			||||||
 | 
					wmemmove_valid_same
 | 
				
			||||||
 | 
					wmemmove_valid_mismatched
 | 
				
			||||||
 | 
					wmemset_buffer_overflow
 | 
				
			||||||
 | 
					wmemset_valid_same
 | 
				
			||||||
 | 
					wmemset_valid_mismatched
 | 
				
			||||||
__pycache__/
 | 
					__pycache__/
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,7 +67,33 @@ EXECUTABLES := \
 | 
				
			||||||
    invalid_malloc_object_size_small \
 | 
					    invalid_malloc_object_size_small \
 | 
				
			||||||
    invalid_malloc_object_size_small_quarantine \
 | 
					    invalid_malloc_object_size_small_quarantine \
 | 
				
			||||||
    impossibly_large_malloc \
 | 
					    impossibly_large_malloc \
 | 
				
			||||||
    realloc_init
 | 
					    realloc_init \
 | 
				
			||||||
 | 
					    memcpy_buffer_overflow \
 | 
				
			||||||
 | 
					    memcpy_read_overflow \
 | 
				
			||||||
 | 
					    memcpy_valid_same \
 | 
				
			||||||
 | 
					    memcpy_valid_mismatched \
 | 
				
			||||||
 | 
					    memccpy_buffer_overflow \
 | 
				
			||||||
 | 
					    memccpy_read_overflow \
 | 
				
			||||||
 | 
					    memccpy_valid_same \
 | 
				
			||||||
 | 
					    memccpy_valid_mismatched \
 | 
				
			||||||
 | 
					    memmove_buffer_overflow \
 | 
				
			||||||
 | 
					    memmove_read_overflow \
 | 
				
			||||||
 | 
					    memmove_valid_same \
 | 
				
			||||||
 | 
					    memmove_valid_mismatched \
 | 
				
			||||||
 | 
					    memset_buffer_overflow \
 | 
				
			||||||
 | 
					    memset_valid_same \
 | 
				
			||||||
 | 
					    memset_valid_mismatched \
 | 
				
			||||||
 | 
					    wmemcpy_buffer_overflow \
 | 
				
			||||||
 | 
					    wmemcpy_read_overflow \
 | 
				
			||||||
 | 
					    wmemcpy_valid_same \
 | 
				
			||||||
 | 
					    wmemcpy_valid_mismatched \
 | 
				
			||||||
 | 
					    wmemmove_buffer_overflow \
 | 
				
			||||||
 | 
					    wmemmove_read_overflow \
 | 
				
			||||||
 | 
					    wmemmove_valid_same \
 | 
				
			||||||
 | 
					    wmemmove_valid_mismatched \
 | 
				
			||||||
 | 
					    wmemset_buffer_overflow \
 | 
				
			||||||
 | 
					    wmemset_valid_same \
 | 
				
			||||||
 | 
					    wmemset_valid_mismatched
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all: $(EXECUTABLES)
 | 
					all: $(EXECUTABLES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/memccpy_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memccpy_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);
 | 
				
			||||||
 | 
					    memccpy(firstbuffer, secondbuffer, 'b', 32);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/memccpy_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memccpy_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);
 | 
				
			||||||
 | 
					    memccpy(firstbuffer, secondbuffer, 'b', 32);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/memccpy_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memccpy_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);
 | 
				
			||||||
 | 
					    memccpy(firstbuffer, secondbuffer, 'b', 16);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/memccpy_valid_same.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/memccpy_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);
 | 
				
			||||||
 | 
					    memccpy(firstbuffer, secondbuffer, 'b', 16);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										155
									
								
								test/test_smc.py
									
										
									
									
									
								
							
							
						
						
									
										155
									
								
								test/test_smc.py
									
										
									
									
									
								
							| 
						 | 
					@ -238,5 +238,160 @@ class TestSimpleMemoryCorruption(unittest.TestCase):
 | 
				
			||||||
            "realloc_init")
 | 
					            "realloc_init")
 | 
				
			||||||
        self.assertEqual(returncode, 0)
 | 
					        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_memccpy_buffer_overflow(self):
 | 
				
			||||||
 | 
					    #    _stdout, stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					    #        "memccpy_buffer_overflow")
 | 
				
			||||||
 | 
					    #    self.assertEqual(returncode, -6)
 | 
				
			||||||
 | 
					    #    self.assertEqual(stderr.decode(
 | 
				
			||||||
 | 
					    #        "utf-8"), "fatal allocator error: memccpy buffer overflow\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #def test_memccpy_read_overflow(self):
 | 
				
			||||||
 | 
					    #    _stdout, stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					    #        "memccpy_read_overflow")
 | 
				
			||||||
 | 
					    #    self.assertEqual(returncode, -6)
 | 
				
			||||||
 | 
					    #    self.assertEqual(stderr.decode(
 | 
				
			||||||
 | 
					    #        "utf-8"), "fatal allocator error: memccpy read overflow\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_memccpy_valid_same(self):
 | 
				
			||||||
 | 
					        _stdout, _stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					            "memccpy_valid_same")
 | 
				
			||||||
 | 
					        self.assertEqual(returncode, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_memccpy_valid_mismatched(self):
 | 
				
			||||||
 | 
					        _stdout, _stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					            "memccpy_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_wmemcpy_buffer_overflow(self):
 | 
				
			||||||
 | 
					    #    _stdout, stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					    #        "wmemcpy_buffer_overflow")
 | 
				
			||||||
 | 
					    #    self.assertEqual(returncode, -6)
 | 
				
			||||||
 | 
					    #    self.assertEqual(stderr.decode(
 | 
				
			||||||
 | 
					    #        "utf-8"), "fatal allocator error: wmemcpy buffer overflow\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #def test_wmemcpy_read_overflow(self):
 | 
				
			||||||
 | 
					    #    _stdout, stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					    #        "wmemcpy_read_overflow")
 | 
				
			||||||
 | 
					    #    self.assertEqual(returncode, -6)
 | 
				
			||||||
 | 
					    #    self.assertEqual(stderr.decode(
 | 
				
			||||||
 | 
					    #        "utf-8"), "fatal allocator error: wmemcpy read overflow\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_wmemcpy_valid_same(self):
 | 
				
			||||||
 | 
					        _stdout, _stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					            "wmemcpy_valid_same")
 | 
				
			||||||
 | 
					        self.assertEqual(returncode, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_wmemcpy_valid_mismatched(self):
 | 
				
			||||||
 | 
					        _stdout, _stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					            "wmemcpy_valid_mismatched")
 | 
				
			||||||
 | 
					        self.assertEqual(returncode, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #def test_wmemmove_buffer_overflow(self):
 | 
				
			||||||
 | 
					    #    _stdout, stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					    #        "wmemmove_buffer_overflow")
 | 
				
			||||||
 | 
					    #    self.assertEqual(returncode, -6)
 | 
				
			||||||
 | 
					    #    self.assertEqual(stderr.decode(
 | 
				
			||||||
 | 
					    #        "utf-8"), "fatal allocator error: wmemmove buffer overflow\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #def test_wmemmove_read_overflow(self):
 | 
				
			||||||
 | 
					    #    _stdout, stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					    #        "wmemmove_read_overflow")
 | 
				
			||||||
 | 
					    #    self.assertEqual(returncode, -6)
 | 
				
			||||||
 | 
					    #    self.assertEqual(stderr.decode(
 | 
				
			||||||
 | 
					    #        "utf-8"), "fatal allocator error: wmemmove read overflow\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_wmemmove_valid_same(self):
 | 
				
			||||||
 | 
					        _stdout, _stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					            "wmemmove_valid_same")
 | 
				
			||||||
 | 
					        self.assertEqual(returncode, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_wmemmove_valid_mismatched(self):
 | 
				
			||||||
 | 
					        _stdout, _stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					            "wmemmove_valid_mismatched")
 | 
				
			||||||
 | 
					        self.assertEqual(returncode, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #def test_wmemset_buffer_overflow(self):
 | 
				
			||||||
 | 
					    #    _stdout, stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					    #        "wmemset_buffer_overflow")
 | 
				
			||||||
 | 
					    #    self.assertEqual(returncode, -6)
 | 
				
			||||||
 | 
					    #    self.assertEqual(stderr.decode(
 | 
				
			||||||
 | 
					    #        "utf-8"), "fatal allocator error: wmemset buffer overflow\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_wmemset_valid_same(self):
 | 
				
			||||||
 | 
					        _stdout, _stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					            "wmemset_valid_same")
 | 
				
			||||||
 | 
					        self.assertEqual(returncode, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_wmemset_valid_mismatched(self):
 | 
				
			||||||
 | 
					        _stdout, _stderr, returncode = self.run_test(
 | 
				
			||||||
 | 
					            "wmemset_valid_mismatched")
 | 
				
			||||||
 | 
					        self.assertEqual(returncode, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    unittest.main()
 | 
					    unittest.main()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/wmemcpy_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/wmemcpy_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *firstbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    wchar_t *secondbuffer = malloc(32 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!firstbuffer && !secondbuffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(secondbuffer, L'\U0001F642', 32);
 | 
				
			||||||
 | 
					    wmemcpy(firstbuffer, secondbuffer, 32);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/wmemcpy_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/wmemcpy_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *firstbuffer = malloc(32 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    wchar_t *secondbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!firstbuffer && !secondbuffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(secondbuffer, L'\U0001F642', 16);
 | 
				
			||||||
 | 
					    wmemcpy(firstbuffer, secondbuffer, 32);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/wmemcpy_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/wmemcpy_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *firstbuffer = malloc(32 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    wchar_t *secondbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!firstbuffer && !secondbuffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(secondbuffer, L'\U0001F642', 16);
 | 
				
			||||||
 | 
					    wmemcpy(firstbuffer, secondbuffer, 16);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/wmemcpy_valid_same.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/wmemcpy_valid_same.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *firstbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    wchar_t *secondbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!firstbuffer && !secondbuffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(secondbuffer, L'\U0001F642', 16);
 | 
				
			||||||
 | 
					    wmemcpy(firstbuffer, secondbuffer, 16);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/wmemmove_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/wmemmove_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *firstbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    wchar_t *secondbuffer = malloc(32 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!firstbuffer && !secondbuffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(secondbuffer, L'\U0001F642', 32);
 | 
				
			||||||
 | 
					    wmemmove(firstbuffer, secondbuffer, 32);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/wmemmove_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/wmemmove_read_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *firstbuffer = malloc(32 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    wchar_t *secondbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!firstbuffer && !secondbuffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(secondbuffer, L'\U0001F642', 16);
 | 
				
			||||||
 | 
					    wmemmove(firstbuffer, secondbuffer, 32);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/wmemmove_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/wmemmove_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *firstbuffer = malloc(32 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    wchar_t *secondbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!firstbuffer && !secondbuffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(secondbuffer, L'\U0001F642', 16);
 | 
				
			||||||
 | 
					    wmemmove(firstbuffer, secondbuffer, 16);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								test/wmemmove_valid_same.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/wmemmove_valid_same.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *firstbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    wchar_t *secondbuffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!firstbuffer && !secondbuffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(secondbuffer, L'\U0001F642', 16);
 | 
				
			||||||
 | 
					    wmemmove(firstbuffer, secondbuffer, 16);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								test/wmemset_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/wmemset_buffer_overflow.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *buffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!buffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(buffer, L'\U0001F642', 32);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								test/wmemset_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/wmemset_valid_mismatched.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *buffer = malloc(32 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!buffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(buffer, L'\U0001F642', 16);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								test/wmemset_valid_same.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								test/wmemset_valid_same.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "test_util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OPTNONE int main(void) {
 | 
				
			||||||
 | 
					    wchar_t *buffer = malloc(16 * sizeof(wchar_t));
 | 
				
			||||||
 | 
					    if (!buffer) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    wmemset(buffer, L'\U0001F642', 16);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								wmemset.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								wmemset.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					#include "musl.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Copied from musl libc version 1.2.5 licensed under the MIT license */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <wchar.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					wchar_t *musl_wmemset(wchar_t *d, wchar_t c, size_t n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						wchar_t *ret = d;
 | 
				
			||||||
 | 
						while (n--) *d++ = c;
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue