]>
Commit | Line | Data |
---|---|---|
3f92dc2f JJ |
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | #pragma once | |
3 | ||
4 | #include <stddef.h> | |
5 | ||
493cd503 | 6 | #if SD_BOOT |
3f92dc2f JJ |
7 | # include "efi-string.h" |
8 | #else | |
9 | # include <string.h> | |
10 | #endif | |
11 | ||
12 | #include "macro-fundamental.h" | |
13 | ||
493cd503 | 14 | #if !SD_BOOT && HAVE_EXPLICIT_BZERO |
3f92dc2f JJ |
15 | static inline void *explicit_bzero_safe(void *p, size_t l) { |
16 | if (p && l > 0) | |
17 | explicit_bzero(p, l); | |
18 | ||
19 | return p; | |
20 | } | |
21 | #else | |
22 | static inline void *explicit_bzero_safe(void *p, size_t l) { | |
23 | if (p && l > 0) { | |
24 | memset(p, 0, l); | |
25 | __asm__ __volatile__("" : : "r"(p) : "memory"); | |
26 | } | |
27 | return p; | |
28 | } | |
29 | #endif | |
30 | ||
31 | struct VarEraser { | |
5040b2cf LP |
32 | /* NB: This is a pointer to memory to erase in case of CLEANUP_ERASE(). Pointer to pointer to memory |
33 | * to erase in case of CLEANUP_ERASE_PTR() */ | |
3f92dc2f JJ |
34 | void *p; |
35 | size_t size; | |
36 | }; | |
37 | ||
38 | static inline void erase_var(struct VarEraser *e) { | |
39 | explicit_bzero_safe(e->p, e->size); | |
40 | } | |
41 | ||
42 | /* Mark var to be erased when leaving scope. */ | |
5040b2cf LP |
43 | #define CLEANUP_ERASE(var) \ |
44 | _cleanup_(erase_var) _unused_ struct VarEraser CONCATENATE(_eraser_, UNIQ) = { \ | |
45 | .p = &(var), \ | |
46 | .size = sizeof(var), \ | |
47 | } | |
48 | ||
49 | static inline void erase_varp(struct VarEraser *e) { | |
50 | ||
51 | /* Very similar to erase_var(), but assumes `p` is a pointer to a pointer whose memory shall be destructed. */ | |
52 | if (!e->p) | |
53 | return; | |
54 | ||
55 | explicit_bzero_safe(*(void**) e->p, e->size); | |
56 | } | |
57 | ||
58 | /* Mark pointer so that memory pointed to is erased when leaving scope. Note: this takes a pointer to the | |
59 | * specified pointer, instead of just a copy of it. This is to allow callers to invalidate the pointer after | |
60 | * use, if they like, disabling our automatic erasure (for example because they succeeded with whatever they | |
61 | * wanted to do and now intend to return the allocated buffer to their caller without it being erased). */ | |
62 | #define CLEANUP_ERASE_PTR(ptr, sz) \ | |
63 | _cleanup_(erase_varp) _unused_ struct VarEraser CONCATENATE(_eraser_, UNIQ) = { \ | |
64 | .p = (ptr), \ | |
65 | .size = (sz), \ | |
66 | } |