From 76af1b049b5d475295668f61def4747780ed8d99 Mon Sep 17 00:00:00 2001 From: Pablo Rincon Date: Fri, 27 Aug 2010 15:59:37 +0200 Subject: [PATCH] Make malloc errors on initialization stage a fatal error, resulting on a exit() call --- src/app-layer-detect-proto.c | 4 +- src/detect-content.c | 40 ++++++++++++------ src/detect-engine-mpm.c | 1 + src/suricata.c | 18 ++++++++ src/suricata.h | 7 ++++ src/tmqh-packetpool.c | 11 ++++- src/tmqh-ringbuffer.c | 8 ++++ src/util-debug.c | 12 ++++-- src/util-error.c | 1 + src/util-host-os-info.c | 14 +++++-- src/util-mem.h | 79 ++++++++++++++++++++++++++++-------- src/util-mpm-b2g.c | 7 ++++ src/util-radix-tree.c | 21 ++++++---- src/util-spm-bm.c | 13 ++++-- src/util-spm-bm.h | 2 +- 15 files changed, 189 insertions(+), 49 deletions(-) diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index c1ae2a70c0..0a24887d20 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -105,11 +105,13 @@ void AlpProtoInit(AlpProtoDetectCtx *ctx) { * \param ctx the contex * \param co the content match * \param proto the proto id + * \initonly */ static void AlpProtoAddSignature(AlpProtoDetectCtx *ctx, DetectContentData *co, uint16_t ip_proto, uint16_t proto) { AlpProtoSignature *s = SCMalloc(sizeof(AlpProtoSignature)); if (s == NULL) { - return; + SCLogError(SC_ERR_FATAL, "Error allocating memory. Signature not loaded. Not enough memory so.. exiting.."); + exit(EXIT_FAILURE); } memset(s, 0x00, sizeof(AlpProtoSignature)); diff --git a/src/detect-content.c b/src/detect-content.c index f310f607f0..491e2da5f3 100644 --- a/src/detect-content.c +++ b/src/detect-content.c @@ -64,6 +64,10 @@ uint32_t DetectContentMaxId(DetectEngineCtx *de_ctx) { return MpmPatternIdStoreGetMaxId(de_ctx->mpm_pattern_id_store); } +/** + * \brief DetectContentParse + * \initonly + */ DetectContentData *DetectContentParse (char *contentstr) { DetectContentData *cd = NULL; @@ -74,8 +78,8 @@ DetectContentData *DetectContentParse (char *contentstr) uint16_t slen = 0; if ((temp = SCStrdup(contentstr)) == NULL) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); - goto error; + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory. Exiting..."); + exit(EXIT_FAILURE); } if (strlen(temp) == 0) { @@ -84,8 +88,11 @@ DetectContentData *DetectContentParse (char *contentstr) } cd = SCMalloc(sizeof(DetectContentData)); - if (cd == NULL) - goto error; + if (cd == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory. Exiting..."); + exit(EXIT_FAILURE); + } + memset(cd, 0, sizeof(DetectContentData)); /* skip the first spaces */ @@ -96,19 +103,26 @@ DetectContentData *DetectContentParse (char *contentstr) if (temp[pos] == '!') { SCFree(temp); - if ((temp = SCStrdup(contentstr + pos + 1)) == NULL) - goto error; + if ((temp = SCStrdup(contentstr + pos + 1)) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "error allocating memory. exiting..."); + exit(EXIT_FAILURE); + } cd->flags |= DETECT_CONTENT_NEGATED; } if (temp[pos] == '\"' && temp[strlen(temp)-1] == '\"') { - if ((str = SCStrdup(temp + pos + 1)) == NULL) - goto error; + if ((str = SCStrdup(temp + pos + 1)) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "error allocating memory. exiting..."); + exit(EXIT_FAILURE); + } + str[strlen(temp) - pos - 2] = '\0'; } else { - if ((str = SCStrdup(temp + pos)) == NULL) - goto error; + if ((str = SCStrdup(temp + pos)) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "error allocating memory. exiting..."); + exit(EXIT_FAILURE); + } } SCFree(temp); @@ -216,8 +230,10 @@ DetectContentData *DetectContentParse (char *contentstr) } cd->content = SCMalloc(len); - if (cd->content == NULL) - goto error; + if (cd->content == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "error allocating memory. exiting..."); + exit(EXIT_FAILURE); + } memcpy(cd->content, str, len); cd->content_len = len; diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 5cd61f71ed..f5d2fe96ac 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -1597,6 +1597,7 @@ uint32_t MpmPatternIdStoreGetMaxId(MpmPatternIdStore *ht) { * \param co content pattern data * * \retval id pattern id + * \initonly */ uint32_t DetectContentGetId(MpmPatternIdStore *ht, DetectContentData *co) { SCEnter(); diff --git a/src/suricata.c b/src/suricata.c index 0c651aa32f..f62f2847e8 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -34,6 +34,7 @@ #include "threads.h" #include "threadvars.h" +#include "util-atomic.h" #include "util-spm.h" #include "util-hash.h" #include "util-hashlist.h" @@ -142,6 +143,7 @@ #include "tmqh-packetpool.h" #include "util-ringbuffer.h" +#include "util-mem.h" /* * we put this here, because we only use it here in main. @@ -150,6 +152,13 @@ volatile sig_atomic_t sigint_count = 0; volatile sig_atomic_t sighup_count = 0; volatile sig_atomic_t sigterm_count = 0; +/* + * Flag to indicate if the engine is at the initialization + * or already processing packets. 2 stages: SURICATA_INIT, + * SURICATA_RUNTIME and SURICATA_FINALIZE + */ +SC_ATOMIC_DECLARE(unsigned int, engine_stage); + /* Max packets processed simultaniously. */ #define DEFAULT_MAX_PENDING_PACKETS 50 @@ -372,6 +381,8 @@ int main(int argc, char **argv) sc_set_caps = FALSE; + SC_ATOMIC_INIT(engine_stage); + /* initialize the logging subsys */ SCLogInitLogModule(NULL); @@ -1108,6 +1119,8 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } + SC_ATOMIC_CAS(&engine_stage, SURICATA_INIT, SURICATA_RUNTIME); + /* Un-pause all the paused threads */ TmThreadContinueThreads(); @@ -1166,6 +1179,9 @@ int main(int argc, char **argv) usleep(100); } + /* Update the engine stage/status flag */ + SC_ATOMIC_CAS(&engine_stage, SURICATA_RUNTIME, SURICATA_DEINIT); + FlowShutdown(); FlowPrintQueueInfo(); @@ -1235,5 +1251,7 @@ int main(int argc, char **argv) return 0; } #endif /* OS_WIN32 */ + + SC_ATOMIC_DESTROY(engine_stage); exit(EXIT_SUCCESS); } diff --git a/src/suricata.h b/src/suricata.h index 6b25a62068..42125c54e1 100644 --- a/src/suricata.h +++ b/src/suricata.h @@ -51,6 +51,13 @@ enum { MODE_DAG, }; +/* Engine stage/status*/ +enum { + SURICATA_INIT = 0, + SURICATA_RUNTIME, + SURICATA_DEINIT +}; + /* queue's between various other threads * XXX move to the TmQueue structure later */ diff --git a/src/tmqh-packetpool.c b/src/tmqh-packetpool.c index dff81ba38e..1cc028b675 100644 --- a/src/tmqh-packetpool.c +++ b/src/tmqh-packetpool.c @@ -44,15 +44,24 @@ #include "tmqh-packetpool.h" #include "util-ringbuffer.h" +#include "util-debug.h" +#include "util-error.h" static RingBuffer16 *ringbuffer = NULL; - +/** + * \brief TmqhPacketpoolRegister + * \initonly + */ void TmqhPacketpoolRegister (void) { tmqh_table[TMQH_PACKETPOOL].name = "packetpool"; tmqh_table[TMQH_PACKETPOOL].InHandler = TmqhInputPacketpool; tmqh_table[TMQH_PACKETPOOL].OutHandler = TmqhOutputPacketpool; ringbuffer = RingBufferInit(); + if (ringbuffer == NULL) { + SCLogError(SC_ERR_FATAL, "Error registering Packet pool handler (at ring buffer init)"); + exit(EXIT_FAILURE); + } } int PacketPoolIsEmpty(void) { diff --git a/src/tmqh-ringbuffer.c b/src/tmqh-ringbuffer.c index b0d84b72b2..e2d790454c 100644 --- a/src/tmqh-ringbuffer.c +++ b/src/tmqh-ringbuffer.c @@ -43,6 +43,10 @@ Packet *TmqhInputRingBufferSrMw(ThreadVars *t); void TmqhOutputRingBufferSrMw(ThreadVars *t, Packet *p); void TmqhInputRingBufferShutdownHandler(ThreadVars *); +/** + * \brief TmqhRingBufferRegister + * \initonly + */ void TmqhRingBufferRegister (void) { tmqh_table[TMQH_RINGBUFFER_MRSW].name = "ringbuffer_mrsw"; tmqh_table[TMQH_RINGBUFFER_MRSW].InHandler = TmqhInputRingBufferMrSw; @@ -64,6 +68,10 @@ void TmqhRingBufferRegister (void) { int i = 0; for (i = 0; i < 256; i++) { ringbuffers[i] = RingBuffer8Init(); + if (ringbuffers[i] == NULL) { + SCLogError(SC_ERR_FATAL, "Error allocating memory to register Ringbuffers. Exiting..."); + exit(EXIT_FAILURE); + } } } diff --git a/src/util-debug.c b/src/util-debug.c index aa69cde36b..47723e690b 100644 --- a/src/util-debug.c +++ b/src/util-debug.c @@ -524,6 +524,7 @@ SCLogOPBuffer *SCLogAllocLogOPBuffer(void) * \brief Returns a new output_interface_context * * \retval iface_ctx Pointer to a newly allocated output_interface_context + * \initonly */ static inline SCLogOPIfaceCtx *SCLogAllocLogOPIfaceCtx() { @@ -547,6 +548,7 @@ static inline SCLogOPIfaceCtx *SCLogAllocLogOPIfaceCtx() * \param log_level Override of the global_log_level by this interface * * \retval iface_ctx Pointer to the file output interface context created + * \initonly */ static inline SCLogOPIfaceCtx *SCLogInitFileOPIface(const char *file, const char *log_format, @@ -607,6 +609,7 @@ error: * \param log_level Override of the global_log_level by this interface * * \retval iface_ctx Pointer to the console output interface context created + * \initonly */ static inline SCLogOPIfaceCtx *SCLogInitConsoleOPIface(const char *log_format, SCLogLevel log_level) @@ -934,13 +937,16 @@ static inline void SCLogSetOPFilter(SCLogInitData *sc_lid, SCLogConfig *sc_lc) * conf file * * \retval sc_lid Pointer to the newly created SCLogInitData + * \initonly */ SCLogInitData *SCLogAllocLogInitData(void) { SCLogInitData *sc_lid = NULL; - if ( (sc_lid = malloc(sizeof(SCLogInitData))) == NULL) - return NULL; + if ( (sc_lid = malloc(sizeof(SCLogInitData))) == NULL) { + SCLogError(SC_ERR_FATAL, "Fatal error encountered initializing the logging subsytem. Out of memory. Exiting..."); + exit(EXIT_FAILURE); + } memset(sc_lid, 0, sizeof(SCLogInitData)); return sc_lid; @@ -1073,7 +1079,7 @@ SCLogOPIfaceCtx *SCLogInitOPIfaceCtx(const char *iface_name, * \param sc_lid The initialization data for the logging module. If sc_lid is * NULL, we would stick to the default configuration for the * logging subsystem. - * + * \initonly */ void SCLogInitLogModule(SCLogInitData *sc_lid) { diff --git a/src/util-error.c b/src/util-error.c index d439249014..0347299d2c 100644 --- a/src/util-error.c +++ b/src/util-error.c @@ -77,6 +77,7 @@ const char * SCErrorToString(SCError err) CASE_CODE (SC_ERR_COUNTER_EXCEEDED); CASE_CODE (SC_ERR_INVALID_CHECKSUM); CASE_CODE (SC_ERR_SPRINTF); + CASE_CODE (SC_ERR_FATAL); CASE_CODE (SC_ERR_INVALID_ARGUMENT); CASE_CODE (SC_ERR_SPINLOCK); CASE_CODE (SC_ERR_INVALID_ENUM_MAP); diff --git a/src/util-host-os-info.c b/src/util-host-os-info.c index 9bf1590ea4..59f1b661ea 100644 --- a/src/util-host-os-info.c +++ b/src/util-host-os-info.c @@ -76,8 +76,8 @@ static struct in_addr *SCHInfoValidateIPV4Address(const char *addr_str) struct in_addr *addr = NULL; if ( (addr = SCMalloc(sizeof(struct in_addr))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCHInfoValidateIPV4Address. Exiting..."); - exit(EXIT_FAILURE); + SCLogError(SC_ERR_MEM_ALLOC, "Fatal error encountered in SCHInfoValidateIPV4Address. Mem not allocated"); + return NULL; } if (inet_pton(AF_INET, addr_str, addr) <= 0) { @@ -124,13 +124,16 @@ static struct in6_addr *SCHInfoValidateIPV6Address(const char *addr_str) * \retval user_data On success, pointer to the user_data that has to be sent * along with the key, to be added to the Radix tree; NULL on * failure + * \initonly */ static void *SCHInfoAllocUserDataOSPolicy(const char *host_os) { int *user_data = NULL; - if ( (user_data = SCMalloc(sizeof(int))) == NULL) - return NULL; + if ( (user_data = SCMalloc(sizeof(int))) == NULL) { + SCLogError(SC_ERR_FATAL, "Error allocating memory. Exiting"); + exit(EXIT_FAILURE); + } /* the host os flavour that has to be sent as user data */ if ( (*user_data = SCMapEnumNameToValue(host_os, sc_hinfo_os_policy_map)) == -1) { @@ -199,6 +202,7 @@ static void SCHInfoMaskIPNetblock(uint8_t *stream, int netmask, int bitlen) * * \retval 0 On successfully adding the host os info to the Radix tree * \retval -1 On failure + * \initonly (only specified from config, at the startup) */ int SCHInfoAddHostOSInfo(char *host_os, char *host_os_ip_range, int is_ipv4) { @@ -395,6 +399,8 @@ void SCHInfoCleanResources(void) /** * \brief Load the host os policy information from the configuration. + * + * \initonly (A mem alloc error should cause an exit failure) */ void SCHInfoLoadFromConfig(void) { diff --git a/src/util-mem.h b/src/util-mem.h index af3a23b644..c0c54ab7cd 100644 --- a/src/util-mem.h +++ b/src/util-mem.h @@ -30,6 +30,8 @@ #ifndef __UTIL_MEM_H__ #define __UTIL_MEM_H__ +extern unsigned int engine_stage_sc_atomic__; + /* Use this only if you want to debug memory allocation and free() * It will log a lot of lines more, so think that is a performance killer */ @@ -50,6 +52,10 @@ if (ptrmem == NULL && a > 0) { \ SCLogError(SC_ERR_MEM_ALLOC, "SCMalloc failed: %s, while trying " \ "to allocate %"PRIdMAX" bytes", strerror(errno), (intmax_t)a); \ + if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ + SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ + exit(EXIT_FAILURE); \ + } \ } \ \ global_mem += a; \ @@ -69,6 +75,10 @@ if (ptrmem == NULL && a > 0) { \ SCLogError(SC_ERR_MEM_ALLOC, "SCRealloc failed: %s, while trying " \ "to allocate %"PRIdMAX" bytes", strerror(errno), (intmax_t)a); \ + if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ + SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ + exit(EXIT_FAILURE); \ + } \ } \ \ global_mem += a; \ @@ -88,6 +98,10 @@ if (ptrmem == NULL && a > 0) { \ SCLogError(SC_ERR_MEM_ALLOC, "SCCalloc failed: %s, while trying " \ "to allocate %"PRIdMAX" bytes", strerror(errno), (intmax_t)a); \ + if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ + SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ + exit(EXIT_FAILURE); \ + } \ } \ \ global_mem += a*nm; \ @@ -108,6 +122,10 @@ if (ptrmem == NULL && len > 0) { \ SCLogError(SC_ERR_MEM_ALLOC, "SCStrdup failed: %s, while trying " \ "to allocate %"PRIu64" bytes", strerror(errno), (intmax_t)len); \ + if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ + SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ + exit(EXIT_FAILURE); \ + } \ } \ \ global_mem += len; \ @@ -126,50 +144,79 @@ }) #else /* DBG_MEM_ALLOC */ - #if 0 +/* without any checks */ +#define SCMalloc malloc +#define SCRealloc realloc +#define SCCalloc calloc +#define SCStrdup strdup +#define SCFree(a) free((a)) +#endif + #define SCMalloc(a) ({ \ - void *ptrmem = malloc(a); \ - if (ptrmem == NULL) { \ + void *ptrmem = NULL; \ + \ + ptrmem = malloc(a); \ + if (ptrmem == NULL && a > 0) { \ SCLogError(SC_ERR_MEM_ALLOC, "SCMalloc failed: %s, while trying " \ "to allocate %"PRIdMAX" bytes", strerror(errno), (intmax_t)a); \ + if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ + SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ + exit(EXIT_FAILURE); \ + } \ } \ (void*)ptrmem; \ }) #define SCRealloc(x, a) ({ \ - void *ptrmem = realloc(x, a); \ - if (ptrmem == NULL) { \ + void *ptrmem = NULL; \ + \ + ptrmem = realloc(x, a); \ + if (ptrmem == NULL && a > 0) { \ SCLogError(SC_ERR_MEM_ALLOC, "SCRealloc failed: %s, while trying " \ "to allocate %"PRIdMAX" bytes", strerror(errno), (intmax_t)a); \ + if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ + SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ + exit(EXIT_FAILURE); \ + } \ } \ (void*)ptrmem; \ }) #define SCCalloc(nm, a) ({ \ - void *ptrmem = calloc(nm, a); \ - if (ptrmem == NULL) { \ + void *ptrmem = NULL; \ + \ + ptrmem = calloc(nm, a); \ + if (ptrmem == NULL && a > 0) { \ SCLogError(SC_ERR_MEM_ALLOC, "SCCalloc failed: %s, while trying " \ "to allocate %"PRIdMAX" bytes", strerror(errno), (intmax_t)a); \ + if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ + SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ + exit(EXIT_FAILURE); \ + } \ } \ (void*)ptrmem; \ }) #define SCStrdup(a) ({ \ - char *ptrmem = strdup(a); \ - if (ptrmem == NULL) { \ + char *ptrmem = NULL; \ + size_t len = strlen(a); \ + \ + ptrmem = strdup(a); \ + if (ptrmem == NULL && len > 0) { \ SCLogError(SC_ERR_MEM_ALLOC, "SCStrdup failed: %s, while trying " \ - "to allocate %"PRIdMAX" bytes", strerror(errno), (intmax_t)strlen(a)); \ + "to allocate %"PRIu64" bytes", strerror(errno), (intmax_t)len); \ + if (SC_ATOMIC_GET(engine_stage) == SURICATA_INIT) {\ + SCLogError(SC_ERR_FATAL, "Out of memory. The engine cannot be initialized. Exiting..."); \ + exit(EXIT_FAILURE); \ + } \ } \ (void*)ptrmem; \ }) -#endif -#define SCMalloc malloc -#define SCRealloc realloc -#define SCCalloc calloc -#define SCStrdup strdup -#define SCFree(a) free((a)) +#define SCFree(a) ({ \ + free(a); \ +}) #endif /* DBG_MEM_ALLOC */ diff --git a/src/util-mpm-b2g.c b/src/util-mpm-b2g.c index be0c672b8c..7281441853 100644 --- a/src/util-mpm-b2g.c +++ b/src/util-mpm-b2g.c @@ -123,6 +123,11 @@ void B2gPrintInfo(MpmCtx *mpm_ctx) { printf("\n"); } +/** + * \brief B2gAllocPattern allocates a new pattern structure + * and initialize the data + * \initonly + */ static inline B2gPattern *B2gAllocPattern(MpmCtx *mpm_ctx) { B2gPattern *p = SCMalloc(sizeof(B2gPattern)); if (p == NULL) @@ -275,6 +280,8 @@ void B2gFreePattern(MpmCtx *mpm_ctx, B2gPattern *p) { * \param pid pattern id * \param sid signature id (internal id) * \param flags pattern MPM_PATTERN_* flags + * + * \initonly */ static int B2gAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, uint32_t sid, uint8_t flags) { B2gCtx *ctx = (B2gCtx *)mpm_ctx->ctx; diff --git a/src/util-radix-tree.c b/src/util-radix-tree.c index 3f19bab9e0..5fa56ffd0d 100644 --- a/src/util-radix-tree.c +++ b/src/util-radix-tree.c @@ -141,6 +141,7 @@ static SCRadixUserData *SCRadixAllocSCRadixUserData(uint8_t netmask, void *user) { SCRadixUserData *user_data = SCMalloc(sizeof(SCRadixUserData)); if (user_data == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); return NULL; } @@ -476,8 +477,8 @@ static inline SCRadixNode *SCRadixCreateNode() SCRadixNode *node = NULL; if ( (node = SCMalloc(sizeof(SCRadixNode))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixCreateNode. Exiting..."); - exit(EXIT_FAILURE); + SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixCreateNode. Mem not allocated..."); + return NULL; } memset(node, 0, sizeof(SCRadixNode)); @@ -511,6 +512,8 @@ static void SCRadixReleaseNode(SCRadixNode *node, SCRadixTree *tree) * cleanup API to free the user suppplied data * * \retval tree The newly created radix tree on success + * + * \initonly (all radix trees should be created at init) */ SCRadixTree *SCRadixCreateRadixTree(void (*Free)(void*), void (*PrintData)(void*)) { @@ -615,6 +618,8 @@ static SCRadixNode *SCRadixAddKey(uint8_t *key_stream, uint16_t key_bitlen, /* the very first element in the radix tree */ if (tree->head == NULL) { node = SCRadixCreateNode(); + if (node == NULL) + return NULL; node->prefix = prefix; node->bit = prefix->bitlen; tree->head = node; @@ -632,8 +637,8 @@ static SCRadixNode *SCRadixAddKey(uint8_t *key_stream, uint16_t key_bitlen, node->netmask_cnt++; if ( (node->netmasks = SCRealloc(node->netmasks, (node->netmask_cnt * sizeof(uint8_t)))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixAddKey. Exiting..."); - exit(EXIT_FAILURE); + SCLogError(SC_ERR_MEM_ALLOC, "Fatal error encountered in SCRadixAddKey. Mem not allocated"); + return NULL; } node->netmasks[0] = netmask; return node; @@ -750,8 +755,8 @@ static SCRadixNode *SCRadixAddKey(uint8_t *key_stream, uint16_t key_bitlen, node->netmask_cnt++; if ( (node->netmasks = SCRealloc(node->netmasks, (node->netmask_cnt * sizeof(uint8_t)))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixAddKey. Exiting..."); - exit(EXIT_FAILURE); + SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixAddKey. Mem not allocated..."); + return NULL; } if (node->netmask_cnt == 1) { @@ -822,8 +827,8 @@ static SCRadixNode *SCRadixAddKey(uint8_t *key_stream, uint16_t key_bitlen, if ( (inter_node->netmasks = SCMalloc((node->netmask_cnt - i) * sizeof(uint8_t))) == NULL) { - SCLogError(SC_ERR_FATAL, "Fatal error encountered in SCRadixAddKey. Exiting..."); - exit(EXIT_FAILURE); + SCLogError(SC_ERR_MEM_ALLOC, "Fatal error encountered in SCRadixAddKey. Mem not allocated..."); + return NULL; } for (j = 0; j < (node->netmask_cnt - i); j++) diff --git a/src/util-spm-bm.c b/src/util-spm-bm.c index 4e859f1ced..198f48b262 100644 --- a/src/util-spm-bm.c +++ b/src/util-spm-bm.c @@ -62,6 +62,7 @@ void BoyerMooreCtxToNocase(BmCtx *bm_ctx, uint8_t *needle, uint32_t needle_len) * \param str pointer to the pattern string * \param size length of the string * \retval BmCtx pointer to the newly created Context for the pattern + * \initonly BoyerMoore contexts should be created at init */ BmCtx *BoyerMooreCtxInit(uint8_t *needle, uint32_t needle_len) { BmCtx *new = SCMalloc(sizeof(BmCtx)); @@ -80,7 +81,11 @@ BmCtx *BoyerMooreCtxInit(uint8_t *needle, uint32_t needle_len) { } /* Prepare good Suffixes */ - PreBmGs(needle, needle_len, new->bmGs); + if (PreBmGs(needle, needle_len, new->bmGs) == -1) { + SCLogError(SC_ERR_FATAL, "Fatal error encountered in BooyerMooreCtxInit. Exiting..."); + exit(EXIT_FAILURE); + } + return new; } @@ -153,14 +158,15 @@ void BoyerMooreSuffixes(const uint8_t *x, int32_t m, int32_t *suff) { * \param x pointer to the pattern string * \param m length of the string * \param bmGs pointer to an empty array that will hold the prefixes (shifts) + * \retval 0 ok, -1 failed */ -void PreBmGs(const uint8_t *x, int32_t m, int32_t *bmGs) { +int PreBmGs(const uint8_t *x, int32_t m, int32_t *bmGs) { int32_t i, j; int32_t *suff; suff = SCMalloc(sizeof(int32_t) * (m + 1)); if (suff == NULL) - return; + return -1; BoyerMooreSuffixes(x, m, suff); @@ -178,6 +184,7 @@ void PreBmGs(const uint8_t *x, int32_t m, int32_t *bmGs) { for (i = 0; i <= m - 2; ++i) bmGs[m - 1 - suff[i]] = m - 1 - i; SCFree(suff); + return 0; } /** diff --git a/src/util-spm-bm.h b/src/util-spm-bm.h index 19efddff6b..07008ddf7f 100644 --- a/src/util-spm-bm.h +++ b/src/util-spm-bm.h @@ -42,7 +42,7 @@ BmCtx *BoyerMooreCtxInit(uint8_t *needle, uint32_t needle_len); void BoyerMooreCtxToNocase(BmCtx *, uint8_t *, uint32_t); void PreBmBc(const uint8_t *x, int32_t m, int32_t *bmBc); void BoyerMooreSuffixes(const uint8_t *x, int32_t m, int32_t *suff); -void PreBmGs(const uint8_t *x, int32_t m, int32_t *bmGs); +int PreBmGs(const uint8_t *, int32_t, int32_t *); uint8_t *BoyerMoore(uint8_t *x, int32_t m, uint8_t *y, int32_t n, int32_t *bmGs, int32_t *bmBc); void PreBmBcNocase(const uint8_t *x, int32_t m, int32_t *bmBc); void BoyerMooreSuffixesNocase(const uint8_t *x, int32_t m, int32_t *suff);