diff options
Diffstat (limited to 'src/libnm-systemd-shared/src/fundamental/memory-util-fundamental.h')
-rw-r--r-- | src/libnm-systemd-shared/src/fundamental/memory-util-fundamental.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/libnm-systemd-shared/src/fundamental/memory-util-fundamental.h b/src/libnm-systemd-shared/src/fundamental/memory-util-fundamental.h new file mode 100644 index 0000000000..78e2dbec59 --- /dev/null +++ b/src/libnm-systemd-shared/src/fundamental/memory-util-fundamental.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include <stddef.h> + +#if SD_BOOT +# include "efi-string.h" +#else +# include <string.h> +#endif + +#include "macro-fundamental.h" + +#if !SD_BOOT && HAVE_EXPLICIT_BZERO +static inline void *explicit_bzero_safe(void *p, size_t l) { + if (p && l > 0) + explicit_bzero(p, l); + + return p; +} +#else +static inline void *explicit_bzero_safe(void *p, size_t l) { + if (p && l > 0) { + memset(p, 0, l); + __asm__ __volatile__("" : : "r"(p) : "memory"); + } + return p; +} +#endif + +struct VarEraser { + /* NB: This is a pointer to memory to erase in case of CLEANUP_ERASE(). Pointer to pointer to memory + * to erase in case of CLEANUP_ERASE_PTR() */ + void *p; + size_t size; +}; + +static inline void erase_var(struct VarEraser *e) { + explicit_bzero_safe(e->p, e->size); +} + +/* Mark var to be erased when leaving scope. */ +#define CLEANUP_ERASE(var) \ + _cleanup_(erase_var) _unused_ struct VarEraser CONCATENATE(_eraser_, UNIQ) = { \ + .p = &(var), \ + .size = sizeof(var), \ + } + +static inline void erase_varp(struct VarEraser *e) { + + /* Very similar to erase_var(), but assumes `p` is a pointer to a pointer whose memory shall be destructed. */ + if (!e->p) + return; + + explicit_bzero_safe(*(void**) e->p, e->size); +} + +/* Mark pointer so that memory pointed to is erased when leaving scope. Note: this takes a pointer to the + * specified pointer, instead of just a copy of it. This is to allow callers to invalidate the pointer after + * use, if they like, disabling our automatic erasure (for example because they succeeded with whatever they + * wanted to do and now intend to return the allocated buffer to their caller without it being erased). */ +#define CLEANUP_ERASE_PTR(ptr, sz) \ + _cleanup_(erase_varp) _unused_ struct VarEraser CONCATENATE(_eraser_, UNIQ) = { \ + .p = (ptr), \ + .size = (sz), \ + } |