mirror of
https://github.com/pound-emu/ballistic.git
synced 2026-06-17 04:16:48 -07:00
35ef021fc9
The main focus of this commit is 'bal_safety.h'. This header file adds magic numbers to prevent Undefined Behavior. Right now this has only been added to 'bal_assembler_t'. This introduces 3 magic numbers: #define BAL_MAGIC_UNINITIALIZED 0x00000000U #define BAL_ASSEMBLER_MAGIC_ALIVE 0xBA11A550U #define BAL_ASSEMBLER_MAGIC_DEAD 0xDEADBA11U 'ALIVE' magic numbers will be set only if the struct has been initialized properly. Every function should check a struct's magic number to make sure it's not operating on a memory corrupted struct. 'DEAD' magic numbers should be set on a struct's 'destory()' function. This is done to prevent Double Free and Use-After-Free scenarios. Convenience macro 'BAL_CHECK_MAGIC' and 'BAL_CHECK_MAGIC_VOID' have been added to easily validate struct integrity. Signed-off-by: Ronald Caesar <github43132@proton.me>
93 lines
5.3 KiB
C
93 lines
5.3 KiB
C
#ifndef BALLISTIC_SAFETY_H
|
|
#define BALLISTIC_SAFETY_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif // __cplusplus
|
|
|
|
#define BAL_MAGIC_UNINITIALIZED 0x00000000U
|
|
|
|
#define BAL_ASSEMBLER_MAGIC_ALIVE 0xBA11A550U // BALLISTO
|
|
#define BAL_ASSEMBLER_MAGIC_DEAD 0xDEADBA11U // DEADBALL
|
|
|
|
static const char *bal_decode_magic(uint32_t magic)
|
|
{
|
|
switch (magic)
|
|
{
|
|
case BAL_MAGIC_UNINITIALIZED:
|
|
return "Uninitialized Memory";
|
|
case BAL_ASSEMBLER_MAGIC_ALIVE:
|
|
return "BALLISTO";
|
|
case BAL_ASSEMBLER_MAGIC_DEAD:
|
|
return "DEADBALL";
|
|
default:
|
|
return "Unknown (Likely Buffer Overflow)";
|
|
}
|
|
}
|
|
|
|
static inline const char *bal_diagnose_magic_failure(uint32_t actual_magic, uint32_t dead_magic)
|
|
{
|
|
if (actual_magic == BAL_MAGIC_UNINITIALIZED)
|
|
{
|
|
return "Struct was never initialized.";
|
|
}
|
|
if (actual_magic == dead_magic)
|
|
{
|
|
return "Struct was explicitly destroyed (Double Free?).";
|
|
}
|
|
return "Memory corruption or wrong struct type passed.";
|
|
}
|
|
|
|
#define BAL_CHECK_MAGIC(ptr, alive_magic, dead_magic, struct_name_str, logger) \
|
|
do \
|
|
{ \
|
|
if (BAL_UNLIKELY((ptr)->magic != (alive_magic))) \
|
|
{ \
|
|
BAL_LOG_ERROR(&logger, \
|
|
"\n================================================================\n" \
|
|
"%s INTEGRITY CHECK FAILED!\n" \
|
|
" Expected : 0x%08X (%s)\n" \
|
|
" Actual : 0x%08X (%s)\n" \
|
|
" Reason: %s\n" \
|
|
"================================================================\n", \
|
|
(struct_name_str), \
|
|
(alive_magic), \
|
|
bal_decode_magic(alive_magic), \
|
|
(ptr)->magic, \
|
|
bal_decode_magic((ptr)->magic), \
|
|
bal_diagnose_magic_failure((ptr)->magic, (dead_magic))); \
|
|
(ptr)->status = BAL_ERROR_STRUCT_CORRUPTED; \
|
|
return (BAL_ERROR_STRUCT_CORRUPTED); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define BAL_CHECK_MAGIC_VOID(ptr, alive_magic, dead_magic, struct_name_str, logger) \
|
|
do \
|
|
{ \
|
|
if (BAL_UNLIKELY((ptr)->magic != (alive_magic))) \
|
|
{ \
|
|
BAL_LOG_ERROR(&logger, \
|
|
"\n================================================================\n" \
|
|
"%s INTEGRITY CHECK FAILED!\n" \
|
|
" Expected : 0x%08X (%s)\n" \
|
|
" Actual : 0x%08X (%s)\n" \
|
|
" Reason: %s\n" \
|
|
"================================================================\n", \
|
|
(struct_name_str), \
|
|
(alive_magic), \
|
|
bal_decode_magic(alive_magic), \
|
|
(ptr)->magic, \
|
|
bal_decode_magic((ptr)->magic), \
|
|
bal_diagnose_magic_failure((ptr)->magic, (dead_magic))); \
|
|
(ptr)->status = BAL_ERROR_STRUCT_CORRUPTED; \
|
|
return; \
|
|
} \
|
|
} while (0)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif // __cplusplus
|
|
|
|
#endif // BALLISTIC_SAFETY_H
|