This is a simple C program that implements a stack data structure with added security features, including canary protection and hash protection. The program provides all the basic stack functions.
This C program provides a stack data structure with built-in protection mechanisms, such as canary protection and hash protection. These mechanisms help detect and handle errors that may occur during stack operations, enhancing the security and reliability of the stack. In addition, an html dump is generated for each error detected.
To use this stack algorithm in your C project, follow these steps:
-
Clone the repository or download the source code.
-
Include the
stack.h
header file in your project:#include "stack.h"
-
Implement the functions according to your requirements.
-
Compile your project, ensuring that you link it with the
stack.cpp
source file.
Here's a brief overview of how to use the provided functions in your C program:
-
Initialize a stack using
stackInit
:Stack myStack; StackError initError = stackInit(&myStack); if (initError != NO_ERROR) { // Handle initialization error }
-
Push elements onto the stack using
stackPush
:elem_t element = 42; // Replace with your element StackError pushError = stackPush(&myStack, element); if (pushError != NO_ERROR) { // Handle push error }
-
Pop elements from the stack using
stackPop
:elem_t poppedElement; StackError popError = stackPop(&myStack, &poppedElement); if (popError != NO_ERROR) { // Handle pop error }
-
Perform any other necessary stack operations.
-
When done, release the stack memory using
stackDtor
:StackError dtorError = stackDtor(&myStack); if (dtorError != NO_ERROR) { // Handle destructor error }
#define stackDump(stk, stackError) stackDump_internal((stk), (stackError), __FILE__, __LINE__, __FUNCTION__)
- Description: dumps all relevant stack information along with the given error to the log file (stderr by default).
- Parameters:
stk
- The stack struct.stackError
- The error code.
- Note: you don't need to call
stackDump()
on error, it's done automatically.
#define stackInit(stk) stackInit_internal((stk), StackInitInfo{__FILE__, #stk, __FUNCTION__, __LINE__})
- Description: initializes a stack structure.
- Parameters:
stk
- Stack struct.
- Returns: Error code.
StackError stackPush(Stack* stk, const elem_t elem);
- Description: Puts another element into the stack, allocating more memory if needed.
- Parameters:
stk
- The stack.elem
- The element to push.
- Returns: Error code.
StackError stackPop(Stack* stk, elem_t* elem);
- Description: Puts another element into the stack, allocating more memory if needed.
- Parameters:
stk
- The stack.elem
- Pointer to the variable where the popped element will be stored.
- Returns: Error code.
StackError stackDtor(Stack* stk);
- Description: Destructor for stack structure.
- Parameters:
stk
- Stack struct.
- Returns: Error code.
StackError setLogFile(const char* fileName);
- Description: Automatically creates a log file with the specified name.
- Parameters:
fileName
- The name of the log file.
- Note: Don't forget to call
stackDtor
when you're done to close the file.
This section describes the configurable settings and constants in the code:
RELEASE
mode optimizes the code for performance.- In this mode, unused hash values are not filled with poison.
- Validation is performed only on essential parameters.
CANARY_PROTECT
enhances security by using canary values to protect the stack and data.- While enabling canary protection, keep in mind that it slightly increases the execution time of every stack operation.
- It may also require a slightly larger amount of memory due to the additional canary values.
HASH_PROTECT
strengthens security using a hash function to protect the stack and data.- Enabling hash protection significantly increases the execution time of every stack operation.
elem_t
is the element type used in the stack.canary_t
is the canary type used for data protection.
ELEM_FORMAT
defines the format specifier for printing elements usingprintf()
.CANARY_FORMAT
defines the format specifier for printing canary values.
POISON
is the value used to mark uninitialized elements in the stack.
CANARY_VALUE
is the canary value used to protect data integrity.
STACK_SIZE_DEFAULT
defines the default minimum capacity that the stack can have.
STACK_CAPACITY_MULTIPLIER
specifies the multiplier used to increase the capacity of the stack when needed.
The functions in this stack algorithm may return the following error codes:
NO_ERROR
- no error occurred.DATA_NULL_ERROR
- data is NULL, indicating an uninitialized stack.ELEM_NULL_ERROR
- elem is NULL, which is unexpected.STRUCT_NULL_ERROR
- struct is NULL, indicating an uninitialized stack structure.NEGATIVE_SIZE_ERROR
- size cannot be negative.NEGATIVE_CAPACITY_ERROR
- capacity cannot be negative.SIZE_CAPACITY_ERROR
- size should not exceed capacity.MEMORY_ALLOCATION_ERROR
- error during memory allocation (malloc or realloc).POP_OUT_OF_RANGE_ERROR
- attempted pop operation on an empty stack.OPENING_FILE_ERROR
- failed to open a file.DEAD_STRUCT_CANARY_ERROR
- struct canary value indicates a possible stack attack.DEAD_DATA_CANARY_ERROR
- data canary value indicates a possible stack attack.UNREGISTERED_STRUCT_ACCESS_ERROR
- struct hash mismatch due to unauthorized data manipulation.UNREGISTERED_DATA_ACCESS_ERROR
- data hash mismatch due to unauthorized data manipulation.
You can find usage examples and additional information in the provided code files and documentation. (work in progress)