1*0ac341f1SConrad Meyer
2*0ac341f1SConrad Meyer #include <stdlib.h>
3*0ac341f1SConrad Meyer #include <sys/types.h>
4*0ac341f1SConrad Meyer
5*0ac341f1SConrad Meyer #include <limits.h>
6*0ac341f1SConrad Meyer #include <signal.h>
7*0ac341f1SConrad Meyer
8*0ac341f1SConrad Meyer #define TEST_NAME "sodium_utils2"
9*0ac341f1SConrad Meyer #include "cmptest.h"
10*0ac341f1SConrad Meyer
11*0ac341f1SConrad Meyer #ifdef __SANITIZE_ADDRESS__
12*0ac341f1SConrad Meyer # warning The sodium_utils2 test is expected to fail with address sanitizer
13*0ac341f1SConrad Meyer #endif
14*0ac341f1SConrad Meyer
15*0ac341f1SConrad Meyer #undef sodium_malloc
16*0ac341f1SConrad Meyer #undef sodium_free
17*0ac341f1SConrad Meyer #undef sodium_allocarray
18*0ac341f1SConrad Meyer
19*0ac341f1SConrad Meyer __attribute__((noreturn)) static void
segv_handler(int sig)20*0ac341f1SConrad Meyer segv_handler(int sig)
21*0ac341f1SConrad Meyer {
22*0ac341f1SConrad Meyer (void) sig;
23*0ac341f1SConrad Meyer
24*0ac341f1SConrad Meyer printf("Intentional segfault / bus error caught\n");
25*0ac341f1SConrad Meyer printf("OK\n");
26*0ac341f1SConrad Meyer #ifdef SIGSEGV
27*0ac341f1SConrad Meyer signal(SIGSEGV, SIG_DFL);
28*0ac341f1SConrad Meyer #endif
29*0ac341f1SConrad Meyer #ifdef SIGBUS
30*0ac341f1SConrad Meyer signal(SIGBUS, SIG_DFL);
31*0ac341f1SConrad Meyer #endif
32*0ac341f1SConrad Meyer #ifdef SIGABRT
33*0ac341f1SConrad Meyer signal(SIGABRT, SIG_DFL);
34*0ac341f1SConrad Meyer #endif
35*0ac341f1SConrad Meyer exit(0);
36*0ac341f1SConrad Meyer }
37*0ac341f1SConrad Meyer
38*0ac341f1SConrad Meyer int
main(void)39*0ac341f1SConrad Meyer main(void)
40*0ac341f1SConrad Meyer {
41*0ac341f1SConrad Meyer void * buf;
42*0ac341f1SConrad Meyer size_t size;
43*0ac341f1SConrad Meyer unsigned int i;
44*0ac341f1SConrad Meyer
45*0ac341f1SConrad Meyer if (sodium_malloc(SIZE_MAX - 1U) != NULL) {
46*0ac341f1SConrad Meyer return 1;
47*0ac341f1SConrad Meyer }
48*0ac341f1SConrad Meyer if (sodium_malloc(0U) == NULL) {
49*0ac341f1SConrad Meyer return 1;
50*0ac341f1SConrad Meyer }
51*0ac341f1SConrad Meyer if (sodium_allocarray(SIZE_MAX / 2U + 1U, SIZE_MAX / 2U) != NULL) {
52*0ac341f1SConrad Meyer return 1;
53*0ac341f1SConrad Meyer }
54*0ac341f1SConrad Meyer sodium_free(sodium_allocarray(0U, 0U));
55*0ac341f1SConrad Meyer sodium_free(sodium_allocarray(0U, 1U));
56*0ac341f1SConrad Meyer sodium_free(sodium_allocarray(1U, 0U));
57*0ac341f1SConrad Meyer
58*0ac341f1SConrad Meyer buf = sodium_allocarray(1000U, 50U);
59*0ac341f1SConrad Meyer memset(buf, 0, 50000U);
60*0ac341f1SConrad Meyer sodium_free(buf);
61*0ac341f1SConrad Meyer
62*0ac341f1SConrad Meyer sodium_free(sodium_malloc(0U));
63*0ac341f1SConrad Meyer sodium_free(NULL);
64*0ac341f1SConrad Meyer for (i = 0U; i < 10000U; i++) {
65*0ac341f1SConrad Meyer size = 1U + randombytes_uniform(100000U);
66*0ac341f1SConrad Meyer buf = sodium_malloc(size);
67*0ac341f1SConrad Meyer assert(buf != NULL);
68*0ac341f1SConrad Meyer memset(buf, i, size);
69*0ac341f1SConrad Meyer sodium_mprotect_noaccess(buf);
70*0ac341f1SConrad Meyer sodium_free(buf);
71*0ac341f1SConrad Meyer }
72*0ac341f1SConrad Meyer printf("OK\n");
73*0ac341f1SConrad Meyer
74*0ac341f1SConrad Meyer #ifdef SIGSEGV
75*0ac341f1SConrad Meyer signal(SIGSEGV, segv_handler);
76*0ac341f1SConrad Meyer #endif
77*0ac341f1SConrad Meyer #ifdef SIGBUS
78*0ac341f1SConrad Meyer signal(SIGBUS, segv_handler);
79*0ac341f1SConrad Meyer #endif
80*0ac341f1SConrad Meyer #ifdef SIGABRT
81*0ac341f1SConrad Meyer signal(SIGABRT, segv_handler);
82*0ac341f1SConrad Meyer #endif
83*0ac341f1SConrad Meyer size = 1U + randombytes_uniform(100000U);
84*0ac341f1SConrad Meyer buf = sodium_malloc(size);
85*0ac341f1SConrad Meyer assert(buf != NULL);
86*0ac341f1SConrad Meyer
87*0ac341f1SConrad Meyer /* old versions of asan emit a warning because they don't support mlock*() */
88*0ac341f1SConrad Meyer #ifndef __SANITIZE_ADDRESS__
89*0ac341f1SConrad Meyer sodium_mprotect_readonly(buf);
90*0ac341f1SConrad Meyer sodium_mprotect_readwrite(buf);
91*0ac341f1SConrad Meyer #endif
92*0ac341f1SConrad Meyer
93*0ac341f1SConrad Meyer #if defined(HAVE_CATCHABLE_SEGV) && !defined(__EMSCRIPTEN__) && !defined(__SANITIZE_ADDRESS__)
94*0ac341f1SConrad Meyer sodium_memzero(((unsigned char *) buf) + size, 1U);
95*0ac341f1SConrad Meyer sodium_mprotect_noaccess(buf);
96*0ac341f1SConrad Meyer sodium_free(buf);
97*0ac341f1SConrad Meyer printf("Overflow not caught\n");
98*0ac341f1SConrad Meyer #else
99*0ac341f1SConrad Meyer segv_handler(0);
100*0ac341f1SConrad Meyer #endif
101*0ac341f1SConrad Meyer return 0;
102*0ac341f1SConrad Meyer }
103