xref: /freebsd/sys/contrib/libsodium/test/default/sodium_utils2.c (revision 0ac341f145426f1f0d00b64d35f19fada2be635c)
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
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
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