Bitcoin Core 28.99.0
P2P Digital Currency
checkmem.h
Go to the documentation of this file.
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#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# 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# 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#define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
100#endif
101
102#endif /* SECP256K1_CHECKMEM_H */