Coverage Report

Created: 2025-02-21 14:37

/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 */