186 lines
5.9 KiB
C
186 lines
5.9 KiB
C
#include "include/conf.h"
|
|
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <locale.h>
|
|
#include <unistd.h>
|
|
|
|
#include "include/def.h"
|
|
#include "include/file.h"
|
|
#include "include/vessel.h"
|
|
|
|
#ifndef SECURITY
|
|
# include <alloca.h>
|
|
#endif
|
|
|
|
const char *vs_vessel_version = VS_VESSEL_HEADER_VERSION;
|
|
vs_Logger vs_vessel_lg = VS_LOG_ALL;
|
|
|
|
static bool vs_validate_version(const char *version) {
|
|
if (!version || strlen(version) != 7) {
|
|
return false;
|
|
}
|
|
|
|
uint8_t dots = 0;
|
|
|
|
for (uint8_t idx = 0; idx < 7; ++idx) {
|
|
if (version[idx] == '.') {
|
|
++dots;
|
|
} else if (!isdigit(version[idx])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return dots == 2;
|
|
}
|
|
|
|
static void vs_check_version(const char *version) {
|
|
if (!version || !vs_validate_version(version)) {
|
|
vs_flog_error(&vs_vessel_lg,
|
|
"Vessel: Invalid version " VS_CLR_BOLD "%s" VS_CLR_RESET
|
|
" - this is a bug in the original "
|
|
"vessel_require call in the webapp. Please contact the "
|
|
"developer of this application. Could either be from a changed "
|
|
"versioning system, or an outdated version of Vessel.",
|
|
version);
|
|
exit(1);
|
|
}
|
|
|
|
if (strcmp(version, vs_vessel_version) != 0) {
|
|
vs_flog_error(&vs_vessel_lg,
|
|
"Vessel: Expected version " VS_CLR_BOLD "%s" VS_CLR_RESET
|
|
", but got " VS_CLR_BOLD "%s" VS_CLR_RESET ". Please update your "
|
|
"installation of Vessel, and only then try to run this "
|
|
"application.",
|
|
version,
|
|
vs_vessel_version);
|
|
exit(1);
|
|
}
|
|
|
|
vs_flog_info(&vs_vessel_lg,
|
|
"You are running Vessel version " VS_CLR_BOLD "%s" VS_CLR_RESET ".",
|
|
vs_vessel_version);
|
|
}
|
|
|
|
static void vs_check_heap_memory(void) {
|
|
/* Heap memory: At least ~256 MB */
|
|
|
|
uint64_t *heap_mem = malloc(1024 * 1024 * 256);
|
|
|
|
if (!heap_mem) {
|
|
vs_log_error(&vs_vessel_lg,
|
|
"Vessel: You don't have enough heap (physical) "
|
|
"memory to run vessel. At "
|
|
"least 256 MB is required to run Vessel.");
|
|
exit(1);
|
|
}
|
|
|
|
heap_mem[0] = 11824633134348737999ULL;
|
|
heap_mem[1] = 1;
|
|
heap_mem[42023] = 12211069607033963819ULL;
|
|
|
|
if (heap_mem[0] != 11824633134348737999ULL || heap_mem[1] != 1 ||
|
|
heap_mem[42023] != 12211069607033963819ULL) {
|
|
vs_log_error(&vs_vessel_lg,
|
|
"Vessel: 256 MB of heap memory was allocated, "
|
|
"although, write checks failed.");
|
|
free(heap_mem);
|
|
exit(1);
|
|
}
|
|
|
|
vs_flog_info(&vs_vessel_lg,
|
|
"Heap memory: " VS_CLR_BOLD VS_CLR_GREEN "OK" VS_CLR_RESET ". (%p)",
|
|
(void *)heap_mem);
|
|
|
|
free(heap_mem);
|
|
}
|
|
|
|
static void vs_check_stack_memory(void) {
|
|
/* Stack memory: At least ~128 KB. */
|
|
|
|
#ifdef SECURITY
|
|
uint64_t stack_mem[(1024 * 128) / sizeof(uint64_t)]; /* Would use `alloca()` if the stack
|
|
protector didn't complain */
|
|
uint64_t stack_test = 9920702476987689923ULL;
|
|
|
|
if (stack_test != 9920702476987689923ULL) {
|
|
#else
|
|
uint64_t *stack_mem = alloca(1024 * 128);
|
|
uint64_t stack_test = 9920702476987689923ULL;
|
|
|
|
if (!stack_mem || stack_test != 9920702476987689923ULL) {
|
|
#endif
|
|
vs_log_error(&vs_vessel_lg,
|
|
"Vessel: You don't have enough stack "
|
|
"memory to run vessel. At "
|
|
"least 128 KB is required to run Vessel.");
|
|
exit(1);
|
|
}
|
|
|
|
stack_mem[0] = 15881180466282924239ULL;
|
|
stack_mem[1] = 1;
|
|
stack_mem[179] = 17845734011466849539ULL;
|
|
|
|
if (stack_mem[0] != 15881180466282924239ULL || stack_mem[1] != 1 ||
|
|
stack_mem[179] != 17845734011466849539ULL) {
|
|
vs_log_error(&vs_vessel_lg,
|
|
"Vessel: 128 KB of stack memory was allocated, "
|
|
"although, write checks failed.");
|
|
exit(1);
|
|
}
|
|
|
|
vs_flog_info(&vs_vessel_lg,
|
|
"Stack memory: " VS_CLR_BOLD VS_CLR_GREEN "OK" VS_CLR_RESET ". (%p)",
|
|
(void *)stack_mem);
|
|
}
|
|
|
|
void vs_vessel_init(const char *version) {
|
|
vs_check_version(version);
|
|
|
|
/* Misc. single-statement stuff */
|
|
|
|
if (!setlocale(LC_ALL, "")) {
|
|
vs_log_error(&vs_vessel_lg,
|
|
"Vessel: Failed to set the locale for LC_ALL to your default "
|
|
"locale. "
|
|
"Are you sure your locale exists on your system?");
|
|
exit(1);
|
|
}
|
|
|
|
if (!vs_File_ok(VS_FILE_TMPDIR)) {
|
|
vs_log_error(&vs_vessel_lg,
|
|
"Vessel: Exist, read, and/or write checks failed for /tmp/. Please "
|
|
"verify whether it exists, can be written to, and read from.");
|
|
exit(1);
|
|
}
|
|
|
|
/* Check types */
|
|
|
|
if (sizeof(uint8_t) != 1 || sizeof(uint16_t) != 2 || sizeof(uint32_t) != 4 ||
|
|
sizeof(uint64_t) != 8 || sizeof(int8_t) != 1 || sizeof(int16_t) != 2 ||
|
|
sizeof(int32_t) != 4 || sizeof(int64_t) != 8 || sizeof(char) != 1) {
|
|
vs_log_error(&vs_vessel_lg,
|
|
"Vessel: Fixed-size types are not fixed-size, or "
|
|
"`char` not of 8-bit type.");
|
|
exit(1);
|
|
}
|
|
|
|
/*
|
|
* The program may crash at this point due to unavailable memory.
|
|
*
|
|
* Write check magic numbers are just Safe and Sophie Germain prime numbers
|
|
* with at least 50% bit flips.
|
|
*
|
|
* There's nothing special about them, just that they're very improbable to
|
|
* randomly generate and I just like them :)
|
|
*/
|
|
|
|
vs_log_info(&vs_vessel_lg, "Checking heap (256 MB) and stack (128 KB) memory...");
|
|
vs_log_flush();
|
|
vs_check_heap_memory();
|
|
vs_log_flush();
|
|
vs_check_stack_memory();
|
|
|
|
vs_log_info(&vs_vessel_lg, "Your environment is set up correctly.");
|
|
}
|