From 86087e5f9cf4a0512ba36b4d01086b905574a47d Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 11 May 2026 23:15:33 +0200 Subject: Misc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libtest/Makefile | 1 + libtest/TODO | 7 +++ libtest/alloc_have_custom.c | 10 ++-- libtest/common.h | 4 ++ libtest/libtest.h | 18 ++++++ libtest/mmap.c | 27 +++++---- libtest/random.c | 140 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 191 insertions(+), 16 deletions(-) create mode 100644 libtest/TODO create mode 100644 libtest/random.c (limited to 'libtest') diff --git a/libtest/Makefile b/libtest/Makefile index 8eddb00..75a76cd 100644 --- a/libtest/Makefile +++ b/libtest/Makefile @@ -28,6 +28,7 @@ OBJ =\ libtest_stack_on_signal.o\ libtest_get_alloc_failure_in.o\ libtest_set_alloc_failure_in.o\ + random.o\ $(OBJ_BACKTRACE)\ HDR =\ diff --git a/libtest/TODO b/libtest/TODO new file mode 100644 index 0000000..65e2642 --- /dev/null +++ b/libtest/TODO @@ -0,0 +1,7 @@ +libtest_alloc should overallocate and fill the extra data with random +bytes and store a checksum which libtest_free should use to determine +if and out of bounds write has been performed. This requires +libtest_alloc only sets the unusable memory size to what has been +required (rounded up to the next page size multiple for pvalloc). It +may also be a good idea to allocate a few bytes before the returned +address. diff --git a/libtest/alloc_have_custom.c b/libtest/alloc_have_custom.c index d532c3f..9c213bb 100644 --- a/libtest/alloc_have_custom.c +++ b/libtest/alloc_have_custom.c @@ -105,11 +105,11 @@ int libtest_have_custom_valloc(void) { CHECK_CUSTOM_ALLOC(freeable_valloc, 1u); int libtest_have_custom_pvalloc(void) { CHECK_CUSTOM_ALLOC(freeable_pvalloc, 1u); } int libtest_have_custom_memalign(void) { CHECK_CUSTOM_ALLOC(memalign, 1u, 1u); } int libtest_have_custom_aligned_alloc(void) { CHECK_CUSTOM_ALLOC(aligned_alloc, 1u, 1u); } -int libtest_have_custom_strdup(void) { CHECK_CUSTOM_ALLOC(strdup, "x"); } -int libtest_have_custom_strndup(void) { CHECK_CUSTOM_ALLOC(strndup, "x", 1u); } -int libtest_have_custom_wcsdup(void) { CHECK_CUSTOM_ALLOC(wcsdup, (wchar_t[]){1, 0}); } -int libtest_have_custom_wcsndup(void) { CHECK_CUSTOM_ALLOC(wcsndup, &(wchar_t){1}, 1u); } -int libtest_have_custom_memdup(void) { CHECK_CUSTOM_ALLOC(memdup, "x", 1u); } +int libtest_have_custom_strdup(void) { CHECK_CUSTOM_ALLOC(strdup, ""); } +int libtest_have_custom_strndup(void) { CHECK_CUSTOM_ALLOC(strndup, "", 1u); } +int libtest_have_custom_wcsdup(void) { CHECK_CUSTOM_ALLOC(wcsdup, &(wchar_t){0}); } +int libtest_have_custom_wcsndup(void) { CHECK_CUSTOM_ALLOC(wcsndup, &(wchar_t){0}, 1u); } +int libtest_have_custom_memdup(void) { CHECK_CUSTOM_ALLOC(memdup, "", 1u); } int diff --git a/libtest/common.h b/libtest/common.h index 667743a..b78b69d 100644 --- a/libtest/common.h +++ b/libtest/common.h @@ -4,6 +4,10 @@ # include # include #endif +#if defined(__linux__) +# include +# include +#endif #include #include #include diff --git a/libtest/libtest.h b/libtest/libtest.h index b6484b2..41d1a41 100644 --- a/libtest/libtest.h +++ b/libtest/libtest.h @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#include #include #include @@ -402,3 +403,20 @@ size_t libtest_get_alloc_failure_in(void); * a real failure) */ void libtest_set_alloc_failure_in(size_t n); + + +extern unsigned char *libtest_random_pattern; +extern size_t libtest_random_pattern_length; +extern size_t libtest_random_pattern_offset; + +#if defined(__linux__) +extern int libtest_getrandom_real; +extern int libtest_getrandom_error; +extern size_t libtest_getrandom_max_return; +#endif + +extern int libtest_getentropy_real; +extern int libtest_getentropy_error; +extern size_t libtest_getentropy_calls; +extern int libtest_getentropy_jmp_val; +extern jmp_buf libtest_getentropy_jmp; diff --git a/libtest/mmap.c b/libtest/mmap.c index d8a2a60..62ef06e 100644 --- a/libtest/mmap.c +++ b/libtest/mmap.c @@ -2,33 +2,38 @@ #include "common.h" #ifndef TEST -#include - - #if !defined(__linux__) # errno "Don't know how to implement mmap(3), mumap(3), and mremap(3)" #endif +#ifdef SYS_mmap2 +# define IF_MMAP2(A) (A) +#else +# define IF_MMAP2(A) ((void)0) +#endif + +#if defined(__x86_64__) && defined(__ILP32__) /* x32 */ +# define SYSCALL_ARG_MAX LLONG_MAX +#else +# define SYSCALL_ARG_MAX LONG_MAX +#endif + + void * libtest_real_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off) { size_t pagesize = libtest_get_pagesize(); + IF_MMAP2(assert(pagesize == 4096u)); if (off < 0 || off % (off_t)pagesize) goto einval; - off /= (off_t)pagesize; + IF_MMAP2(off /= (off_t)pagesize); -#if defined(__x86_64__) && defined(__ILP32__) /* x32 */ - if (off > LLONG_MAX) + if (off > SYSCALL_ARG_MAX) goto einval; -#else - if (off > LONG_MAX) - goto einval; -#endif #ifdef SYS_mmap2 - assert(pagesize == 4096u); return (void *)syscall(SYS_mmap2, addr, len, prot, flags, fd, off); #else return (void *)syscall(SYS_mmap, addr, len, prot, flags, fd, off); diff --git a/libtest/random.c b/libtest/random.c new file mode 100644 index 0000000..77e9218 --- /dev/null +++ b/libtest/random.c @@ -0,0 +1,140 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + + +unsigned char *libtest_random_pattern = NULL; +size_t libtest_random_pattern_length = 0u; +size_t libtest_random_pattern_offset = 0u; + +static ssize_t +genpattern(void *buf, size_t size) +{ + unsigned char *out = buf; + size_t n; + + if (size > (size_t)SSIZE_MAX) + size = (size_t)SSIZE_MAX; + + if (libtest_random_pattern_length) { + while (size) { + if (libtest_random_pattern_offset == libtest_random_pattern_length) + libtest_random_pattern_offset = 0u; + n = libtest_random_pattern_length - libtest_random_pattern_offset; + if (n > size) + n = size; + memcpy(out, &libtest_random_pattern[libtest_random_pattern_offset], n); + out = &out[n]; + size -= n; + libtest_random_pattern_offset += n; + } + } else { + for (; size; size--, out++) + out[0] = (unsigned char)rand(); + } + + return (ssize_t)size; +} + + +#if defined(__linux__) +int libtest_getrandom_real = 1; +int libtest_getrandom_error = 0; +size_t libtest_getrandom_max_return = SIZE_MAX; + +ssize_t +(getrandom)(void *buf, size_t size, unsigned int flags) +{ + if (size > libtest_getrandom_max_return) + size = libtest_getrandom_max_return; + + if (libtest_getrandom_error) { + errno = libtest_getrandom_error; + if (libtest_getrandom_error == EINTR) + libtest_getrandom_error = 0; + return -1; + } + + if (!libtest_getrandom_real) + return genpattern(buf, size); + +# if defined(SYS_getrandom) + return syscall(SYS_getrandom, buf, size, flags); +# else + errno = ENOSYS; + return -1; +# endif +} +#endif + + +int libtest_getentropy_real = 1; +int libtest_getentropy_error = 0; +size_t libtest_getentropy_calls = 0u; +int libtest_getentropy_jmp_val = 0; +jmp_buf libtest_getentropy_jmp; + +int +(getentropy)(void *buf, size_t size) +{ + unsigned char *out = buf; + ssize_t r; + + libtest_getentropy_calls += 1u; + + if (libtest_getentropy_jmp_val) + longjmp(libtest_getentropy_jmp, libtest_getentropy_jmp_val); + + if (libtest_getentropy_error) { + errno = libtest_getentropy_error; + if (libtest_getentropy_error == EINTR) + libtest_getentropy_error = 0; + return -1; + } + + if (size > 256u) { + errno = EIO; + return -1; + } + + if (!libtest_getentropy_real) { + r = genpattern(out, size); + if (r == (ssize_t)size) + return 0; + errno = EIO; + return -1; + } + +#if defined(__linux__) && defined(SYS_getrandom) + while (size) { + r = (ssize_t)syscall(SYS_getrandom, out, size, 0); + if (r < 0) { + if (errno == EINTR) + continue; + if (errno != ENOSYS) + errno = EIO; + return -1; + } + out = &out[r]; + size -= (size_t)r; + } + return 0; +#else + errno = ENOSYS; + return -1; +#endif +} + + +#else + + +CONST int +main(void) +{ + /* TODO maybe test */ + return 0; +} + + +#endif -- cgit v1.2.3-70-g09d2