/root/bitcoin/src/secp256k1/src/checkmem.h
Line | Count | Source (jump to first uncovered line) |
1 | | /*********************************************************************** |
2 | | * Copyright (c) 2022 Pieter Wuille * |
3 | | * Distributed under the MIT software license, see the accompanying * |
4 | | * file COPYING or https://www.opensource.org/licenses/mit-license.php.* |
5 | | ***********************************************************************/ |
6 | | |
7 | | /* The code here is inspired by Kris Kwiatkowski's approach in |
8 | | * https://github.com/kriskwiatkowski/pqc/blob/main/src/common/ct_check.h |
9 | | * to provide a general interface for memory-checking mechanisms, primarily |
10 | | * for constant-time checking. |
11 | | */ |
12 | | |
13 | | /* These macros are defined by this header file: |
14 | | * |
15 | | * - SECP256K1_CHECKMEM_ENABLED: |
16 | | * - 1 if memory-checking integration is available, 0 otherwise. |
17 | | * This is just a compile-time macro. Use the next macro to check it is actually |
18 | | * available at runtime. |
19 | | * - SECP256K1_CHECKMEM_RUNNING(): |
20 | | * - Acts like a function call, returning 1 if memory checking is available |
21 | | * at runtime. |
22 | | * - SECP256K1_CHECKMEM_CHECK(p, len): |
23 | | * - Assert or otherwise fail in case the len-byte memory block pointed to by p is |
24 | | * not considered entirely defined. |
25 | | * - SECP256K1_CHECKMEM_CHECK_VERIFY(p, len): |
26 | | * - Like SECP256K1_CHECKMEM_CHECK, but only works in VERIFY mode. |
27 | | * - SECP256K1_CHECKMEM_UNDEFINE(p, len): |
28 | | * - marks the len-byte memory block pointed to by p as undefined data (secret data, |
29 | | * in the context of constant-time checking). |
30 | | * - SECP256K1_CHECKMEM_DEFINE(p, len): |
31 | | * - marks the len-byte memory pointed to by p as defined data (public data, in the |
32 | | * context of constant-time checking). |
33 | | * - SECP256K1_CHECKMEM_MSAN_DEFINE(p, len): |
34 | | * - Like SECP256K1_CHECKMEM_DEFINE, but applies only to memory_sanitizer. |
35 | | * |
36 | | */ |
37 | | |
38 | | #ifndef SECP256K1_CHECKMEM_H |
39 | | #define SECP256K1_CHECKMEM_H |
40 | | |
41 | | /* Define a statement-like macro that ignores the arguments. */ |
42 | 0 | #define SECP256K1_CHECKMEM_NOOP(p, len) do { (void)(p); (void)(len); } while(0) |
43 | | |
44 | | /* If compiling under msan, map the SECP256K1_CHECKMEM_* functionality to msan. |
45 | | * Choose this preferentially, even when VALGRIND is defined, as msan-compiled |
46 | | * binaries can't be run under valgrind anyway. */ |
47 | | #if defined(__has_feature) |
48 | | # if __has_feature(memory_sanitizer) |
49 | | # include <sanitizer/msan_interface.h> |
50 | | # define SECP256K1_CHECKMEM_ENABLED 1 |
51 | | # define SECP256K1_CHECKMEM_UNDEFINE(p, len) __msan_allocated_memory((p), (len)) |
52 | | # define SECP256K1_CHECKMEM_DEFINE(p, len) __msan_unpoison((p), (len)) |
53 | | # define SECP256K1_CHECKMEM_MSAN_DEFINE(p, len) __msan_unpoison((p), (len)) |
54 | | # define SECP256K1_CHECKMEM_CHECK(p, len) __msan_check_mem_is_initialized((p), (len)) |
55 | | # define SECP256K1_CHECKMEM_RUNNING() (1) |
56 | | # endif |
57 | | #endif |
58 | | |
59 | | #if !defined SECP256K1_CHECKMEM_MSAN_DEFINE |
60 | 0 | # define SECP256K1_CHECKMEM_MSAN_DEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) |
61 | | #endif |
62 | | |
63 | | /* If valgrind integration is desired (through the VALGRIND define), implement the |
64 | | * SECP256K1_CHECKMEM_* macros using valgrind. */ |
65 | | #if !defined SECP256K1_CHECKMEM_ENABLED |
66 | | # if defined VALGRIND |
67 | | # include <stddef.h> |
68 | | # if defined(__clang__) && defined(__APPLE__) |
69 | | # pragma clang diagnostic push |
70 | | # pragma clang diagnostic ignored "-Wreserved-identifier" |
71 | | # endif |
72 | | # include <valgrind/memcheck.h> |
73 | | # if defined(__clang__) && defined(__APPLE__) |
74 | | # pragma clang diagnostic pop |
75 | | # endif |
76 | | # define SECP256K1_CHECKMEM_ENABLED 1 |
77 | | # define SECP256K1_CHECKMEM_UNDEFINE(p, len) VALGRIND_MAKE_MEM_UNDEFINED((p), (len)) |
78 | | # define SECP256K1_CHECKMEM_DEFINE(p, len) VALGRIND_MAKE_MEM_DEFINED((p), (len)) |
79 | | # define SECP256K1_CHECKMEM_CHECK(p, len) VALGRIND_CHECK_MEM_IS_DEFINED((p), (len)) |
80 | | /* VALGRIND_MAKE_MEM_DEFINED returns 0 iff not running on memcheck. |
81 | | * This is more precise than the RUNNING_ON_VALGRIND macro, which |
82 | | * checks for valgrind in general instead of memcheck specifically. */ |
83 | | # define SECP256K1_CHECKMEM_RUNNING() (VALGRIND_MAKE_MEM_DEFINED(NULL, 0) != 0) |
84 | | # endif |
85 | | #endif |
86 | | |
87 | | /* As a fall-back, map these macros to dummy statements. */ |
88 | | #if !defined SECP256K1_CHECKMEM_ENABLED |
89 | | # define SECP256K1_CHECKMEM_ENABLED 0 |
90 | | # define SECP256K1_CHECKMEM_UNDEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) |
91 | 0 | # define SECP256K1_CHECKMEM_DEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) |
92 | | # define SECP256K1_CHECKMEM_CHECK(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) |
93 | | # define SECP256K1_CHECKMEM_RUNNING() (0) |
94 | | #endif |
95 | | |
96 | | #if defined VERIFY |
97 | | #define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_CHECK((p), (len)) |
98 | | #else |
99 | 0 | #define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_NOOP((p), (len)) |
100 | | #endif |
101 | | |
102 | | #endif /* SECP256K1_CHECKMEM_H */ |