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