From fd6fd9ce4869c13141f3a0c36fa351687e29b5f3 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 27 Feb 2014 11:35:47 +0100 Subject: [PATCH] Fix memory leak in proto - name mapping ==15745== 3 bytes in 1 blocks are definitely lost in loss record 5 of 615 ==15745== at 0x4C2A2DB: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==15745== by 0x71858C1: strdup (strdup.c:42) ==15745== by 0xA20814: SCProtoNameInit (util-proto-name.c:75) ==15745== by 0x952D1B: PostConfLoadedSetup (suricata.c:1983) ==15745== by 0x9537CD: main (suricata.c:2112) Also, clean up and add a check to make sure it's initialized only once. --- src/util-proto-name.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/util-proto-name.c b/src/util-proto-name.c index 7131593cde..82ec8e64ba 100644 --- a/src/util-proto-name.c +++ b/src/util-proto-name.c @@ -27,12 +27,18 @@ #include "suricata-common.h" #include "util-proto-name.h" +static int init_once = 0; + /** * \brief Function to load the protocol names from the specified protocol * file. */ void SCProtoNameInit() { + BUG_ON(init_once); + init_once++; + memset(known_proto, 0x00, sizeof(known_proto)); + /* Load the known protocols name from the /etc/protocols file */ FILE *fp = fopen(PROTO_FILE,"r"); if (fp != NULL) { @@ -46,17 +52,17 @@ void SCProtoNameInit() continue; #if defined(__WIN32) || defined(_WIN32) - char *name = strtok(line," \t"); + char *name = strtok(line," \t"); #else - char *name = strtok_r(line," \t", &ptr); + char *name = strtok_r(line," \t", &ptr); #endif /* __WIN32 */ - if (name == NULL) + if (name == NULL) continue; #if defined(__WIN32) || defined(_WIN32) - char *proto_ch = strtok(NULL," \t"); + char *proto_ch = strtok(NULL," \t"); #else - char *proto_ch = strtok_r(NULL," \t", &ptr); + char *proto_ch = strtok_r(NULL," \t", &ptr); #endif /* __WIN32 */ if (proto_ch == NULL) continue; @@ -66,11 +72,15 @@ void SCProtoNameInit() continue; #if defined(__WIN32) || defined(_WIN32) - char *cname = strtok(NULL, " \t"); + char *cname = strtok(NULL, " \t"); #else - char *cname = strtok_r(NULL, " \t", &ptr); + char *cname = strtok_r(NULL, " \t", &ptr); #endif /* __WIN32 */ + if (known_proto[proto] != NULL) { + SCFree(known_proto[proto]); + } + if (cname != NULL) { known_proto[proto] = SCStrdup(cname); } else { @@ -111,9 +121,10 @@ uint8_t SCProtoNameValid(uint16_t proto) */ void SCProtoNameDeInit() { + int cnt; /* clears the memory of loaded protocol names */ - for (uint8_t cnt=0;cnt < 255;cnt++) { - if(known_proto[cnt] != NULL) + for (cnt = 0; cnt < 255; cnt++) { + if (known_proto[cnt] != NULL) SCFree(known_proto[cnt]); } }