aboutsummaryrefslogtreecommitdiffstats
path: root/libtest
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-05-11 23:15:33 +0200
committerMattias Andrée <m@maandree.se>2026-05-11 23:15:33 +0200
commit86087e5f9cf4a0512ba36b4d01086b905574a47d (patch)
tree03ce90743ef4d9e3da6ba45b70f11494e12b667c /libtest
parentMisc (diff)
downloadlibrecrypt-86087e5f9cf4a0512ba36b4d01086b905574a47d.tar.gz
librecrypt-86087e5f9cf4a0512ba36b4d01086b905574a47d.tar.bz2
librecrypt-86087e5f9cf4a0512ba36b4d01086b905574a47d.tar.xz
Misc
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to '')
-rw-r--r--libtest/Makefile1
-rw-r--r--libtest/TODO7
-rw-r--r--libtest/alloc_have_custom.c10
-rw-r--r--libtest/common.h4
-rw-r--r--libtest/libtest.h18
-rw-r--r--libtest/mmap.c27
-rw-r--r--libtest/random.c140
7 files changed, 191 insertions, 16 deletions
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 <libunwind.h>
# include <elfutils/libdwfl.h>
#endif
+#if defined(__linux__)
+# include <sys/random.h>
+# include <sys/syscall.h>
+#endif
#include <sys/mman.h>
#include <errno.h>
#include <inttypes.h>
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 <setjmp.h>
#include <stddef.h>
#include <signal.h>
@@ -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 <sys/syscall.h>
-
-
#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