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