74 lines
2.3 KiB
C
74 lines
2.3 KiB
C
/*********************************************************************************************\
|
|
* Extended version of be_raise() - SECURITY PATCHED
|
|
*
|
|
* SECURITY IMPROVEMENTS (BM-005 Patch):
|
|
* - Fixed format string vulnerability
|
|
* - Added input validation and bounds checking
|
|
* - Safe string formatting with overflow protection
|
|
* - Enhanced error handling
|
|
\*********************************************************************************************/
|
|
|
|
#include "be_mapping.h"
|
|
#include "be_exec.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
|
|
// SECURITY: Safe format string function - BM-005 patch
|
|
void be_raisef(bvm *vm, const char *except, const char *msg, ...) {
|
|
// SECURITY: Input validation
|
|
#if BE_MAPPING_ENABLE_INPUT_VALIDATION
|
|
if (vm == NULL) {
|
|
return; // Cannot raise exception without VM
|
|
}
|
|
if (except == NULL) {
|
|
except = "internal_error"; // Default exception type
|
|
}
|
|
if (msg == NULL) {
|
|
be_raise(vm, except, "NULL error message");
|
|
return;
|
|
}
|
|
// SECURITY: Validate format string for basic safety
|
|
// Count format specifiers to detect potential format string attacks
|
|
int format_count = 0;
|
|
const char *p = msg;
|
|
while ((p = strchr(p, '%')) != NULL) {
|
|
p++;
|
|
if (*p == '%') {
|
|
p++; // Skip literal %
|
|
continue;
|
|
}
|
|
format_count++;
|
|
if (format_count > 10) { // Reasonable limit
|
|
be_raise(vm, "security_error", "Format string validation failed");
|
|
return;
|
|
}
|
|
}
|
|
#endif // BE_MAPPING_ENABLE_INPUT_VALIDATION
|
|
// To save stack space support logging for max text length of 128 characters
|
|
char log_data[128];
|
|
|
|
va_list arg;
|
|
va_start(arg, msg);
|
|
|
|
// SECURITY: Use safe formatting with bounds checking
|
|
int len = vsnprintf(log_data, sizeof(log_data) - 3, msg, arg);
|
|
va_end(arg);
|
|
|
|
// SECURITY: Handle formatting errors
|
|
if (len < 0) {
|
|
be_raise(vm, except, "Format string error");
|
|
return;
|
|
}
|
|
|
|
// SECURITY: Handle truncation safely
|
|
if (len >= (int)(sizeof(log_data) - 3)) {
|
|
strcat(log_data, "..."); // Indicate truncation
|
|
}
|
|
|
|
// SECURITY: Validate final string before raising
|
|
log_data[sizeof(log_data) - 1] = '\0'; // Ensure null termination
|
|
|
|
be_raise(vm, except, log_data);
|
|
}
|