mirror of
https://gitlab.com/80486DX2-66/gists
synced 2025-01-13 09:42:05 +05:30
C: add mem/safe_mem.*
This commit is contained in:
parent
df611cf964
commit
eb0c6e0dd9
65
c-programming/mem/safe_mem.h
Normal file
65
c-programming/mem/safe_mem.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* safe_mem.h
|
||||
*
|
||||
* A header-only library (macro collection) for safer memory management.
|
||||
*
|
||||
* Author: Intel A80486DX2-66
|
||||
* License: Creative Commons Zero 1.0 Universal
|
||||
*/
|
||||
|
||||
#ifndef _SAFE_MEM_H
|
||||
#define _SAFE_MEM_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SAFE_FREE_ERROR_HOOK /* user-defined */
|
||||
|
||||
#define safe_free(ptr) do { \
|
||||
/* prevents NULL-freeing and double freeing */ \
|
||||
if (ptr != NULL) { \
|
||||
free(ptr); \
|
||||
ptr = NULL; \
|
||||
} else { SAFE_FREE_ERROR_HOOK; } \
|
||||
} while (0)
|
||||
|
||||
#define precise_malloc(nmemb, size) \
|
||||
/* prevents incorrect casting */ \
|
||||
malloc((size_t) nmemb * (size_t) size)
|
||||
|
||||
/* secure_erase(dest, count): erases memory explicitly */
|
||||
#if defined(__FreeBSD__)
|
||||
# define NO_SECURE_ERASE_WARRANTY 0
|
||||
# define SECURE_ERASE_WARRANTY "OpenBSD/FreeBSD: explicit_bzero"
|
||||
|
||||
# include <strings.h>
|
||||
# define secure_erase explicit_bzero
|
||||
#elif defined(_WIN32)
|
||||
# define NO_SECURE_ERASE_WARRANTY 0
|
||||
# define SECURE_ERASE_WARRANTY "Microsoft Windows: SecureZeroMemory"
|
||||
|
||||
# include <windows.h>
|
||||
# define secure_erase SecureZeroMemory
|
||||
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
|
||||
# define NO_SECURE_ERASE_WARRANTY 0
|
||||
# define SECURE_ERASE_WARRANTY "C11+: memset_s"
|
||||
|
||||
# define secure_erase(dest, count) memset_s(dest, count, 0, count)
|
||||
#else
|
||||
# define NO_SECURE_ERASE_WARRANTY 1
|
||||
|
||||
# define __observe__(ptr) do { \
|
||||
if (*ptr == 0) { \
|
||||
++(*ptr); \
|
||||
fprintf(stderr, ""); \
|
||||
} else \
|
||||
--(*ptr); \
|
||||
} while (0)
|
||||
|
||||
# define secure_erase(dest, count) do { \
|
||||
memset(dest, 0, count); \
|
||||
for (size_t i = 0; i < count; i++) \
|
||||
__observe__(dest[i]); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* _SAFE_MEM_H */
|
63
c-programming/mem/safe_mem.test.c
Normal file
63
c-programming/mem/safe_mem.test.c
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* safe_mem.c
|
||||
*
|
||||
* Author: Intel A80486DX2-66
|
||||
* License: Creative Commons Zero 1.0 Universal
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "safe_mem.h"
|
||||
|
||||
#undef SAFE_FREE_ERROR_HOOK
|
||||
#define SAFE_FREE_ERROR_HOOK do { \
|
||||
fprintf(stderr, "Double freeing detected!\n"); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} while (0)
|
||||
|
||||
#define PRINT_POINTER(caption, ptr) \
|
||||
printf(caption " = %p\n", (void*) ptr);
|
||||
#define DUMP_INT_ARRAY(caption, ptr, count) do { \
|
||||
printf("%s: [", caption); \
|
||||
for (size_t i = 0; i < count; i++) { \
|
||||
printf("%d", ptr[i]); \
|
||||
if (i != (count - 1)) \
|
||||
printf(", "); \
|
||||
} \
|
||||
printf("]\n"); \
|
||||
} while (0)
|
||||
|
||||
int main(void) {
|
||||
#define COUNT 4
|
||||
int* integers = precise_malloc(COUNT, sizeof(int));
|
||||
PRINT_POINTER("int* integers (before freeing)", integers);
|
||||
|
||||
integers[0] = 0;
|
||||
integers[1] = EOF;
|
||||
integers[2] = STDERR_FILENO;
|
||||
integers[3] = 1;
|
||||
DUMP_INT_ARRAY("int* integers (before secure erasure)", integers, COUNT);
|
||||
printf("Secure erasure is "
|
||||
#if NO_SECURE_ERASE_WARRANTY
|
||||
"not guaranteed!"
|
||||
#else
|
||||
"guaranteed: %s"
|
||||
#endif
|
||||
"\n"
|
||||
#if !NO_SECURE_ERASE_WARRANTY
|
||||
, SECURE_ERASE_WARRANTY
|
||||
#endif
|
||||
);
|
||||
|
||||
secure_erase(integers, COUNT * sizeof(int));
|
||||
DUMP_INT_ARRAY("int* integers (after secure erasure)", integers, COUNT);
|
||||
|
||||
safe_free(integers);
|
||||
PRINT_POINTER("int* integers (after freeing)", integers);
|
||||
fflush(stdout);
|
||||
safe_free(integers);
|
||||
PRINT_POINTER("int* integers (after two free() calls)", integers);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user