]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/fundamental/memory-util-fundamental.h
Merge pull request #25168 from valentindavid/valentindavid/umount-move-recursive...
[thirdparty/systemd.git] / src / fundamental / memory-util-fundamental.h
CommitLineData
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
15static 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
22static 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
31struct 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
38static 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
49static 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 }