diff --git a/config.c b/config.c index 11b1aa2b..cefba3a9 100644 --- a/config.c +++ b/config.c @@ -82,8 +82,13 @@ void read_FTLconf(void) logg(" QUERY_DISPLAY: Hide queries"); logg("Finished config file parsing"); - free(conflinebuffer); - conflinebuffer = NULL; + + if(conflinebuffer != NULL) + { + free(conflinebuffer); + conflinebuffer = NULL; + } + if(fp != NULL) fclose(fp); } @@ -95,17 +100,22 @@ char *parse_FTLconf(FILE *fp, const char * key) return NULL; char * keystr = calloc(strlen(key)+2,sizeof(char)); - conflinebuffer = calloc(1024,sizeof(char)); - + if(keystr == NULL) + { + logg("WARN: parse_FTLconf failed: could not allocate memory for keystr"); + return NULL; + } sprintf(keystr, "%s=", key); // Go to beginning of file fseek(fp, 0L, SEEK_SET); - while(fgets(conflinebuffer, 1023, fp) != NULL) + size_t size; + errno = 0; + while(getline(&conflinebuffer, &size, fp) != -1) { - // Strip newline from fgets output - conflinebuffer[strlen(conflinebuffer) - 1] = '\0'; + // Strip (possible) newline + conflinebuffer[strcspn(conflinebuffer, "\n")] = '\0'; // Skip comment lines if(conflinebuffer[0] == '#' || conflinebuffer[0] == ';') @@ -120,7 +130,11 @@ char *parse_FTLconf(FILE *fp, const char * key) return (find_equals(conflinebuffer) + 1); } + if(errno == ENOMEM) + logg("WARN: parse_FTLconf failed: could not allocate memory for getline"); + // Key not found -> return NULL free(keystr); + return NULL; } diff --git a/daemon.c b/daemon.c index da07852c..7320d5e7 100644 --- a/daemon.c +++ b/daemon.c @@ -37,15 +37,28 @@ int detect_FTL_process(void) FILE* fp; if((fp = fopen(buffer, "r")) != NULL) { - if (fgets(buffer, sizeof(buffer), fp) != NULL) + char *linebuffer = NULL; + size_t size = 0; + + errno = 0; + if (getline(&linebuffer, &size, fp) != -1) { - if (strstr(buffer, "pihole-FTL") != 0) + if (strstr(linebuffer, "pihole-FTL") != 0) { fclose(fp); - logg("%i - %s", pid, buffer); + logg("%i - %s", pid, linebuffer); return pid; } } + + if(errno == ENOMEM) + logg("WARN: process_pihole_log failed: could not allocate memory for getline"); + + if(linebuffer != NULL) + { + free(linebuffer); + linebuffer = NULL; + } fclose(fp); } } diff --git a/grep.c b/grep.c index 028a48fe..112f1827 100644 --- a/grep.c +++ b/grep.c @@ -74,8 +74,8 @@ int countlines(const char* fname) void readWildcardsList() { FILE *fp; - char *buffer, *domain; - char linebuffer[512]; + char *domain = NULL, *buffer = NULL, *linebuffer = NULL; + size_t size = 0; int i; if((fp = fopen(files.wildcards, "r")) == NULL) { @@ -84,9 +84,23 @@ void readWildcardsList() } // Search through file - while(fgets(linebuffer, 511, fp)) + errno = 0; + while(getline(&linebuffer, &size, fp) != -1) { - buffer = calloc(512,sizeof(char)); + // the read line has always to be larger than what we want to extract, so + // we can use the length as an upper limit for allocating memory for the buffer + + buffer = calloc(size, 1); + if(buffer == NULL) + { + logg("WARN: readWildcardsList failed to allocate memory"); + fclose(fp); + + // Free allocated memory + free(linebuffer); + + return; + } // Try to read up to 511 characters if(sscanf(linebuffer, "address=/%511[^/]/%*[^\n]\n", buffer) > 0) { @@ -112,7 +126,13 @@ void readWildcardsList() break; } } - if(known) continue; + if(known) + { + // Free allocated memory + free(buffer); + buffer = NULL; + continue; + } // Add wildcard entry // Enlarge wildcarddomains pointer array @@ -126,10 +146,22 @@ void readWildcardsList() counters.wildcarddomains++; } } + + // Free allocated memory free(buffer); buffer = NULL; } + if(errno == ENOMEM) + logg("WARN: readWildcardsList failed: could not allocate memory for getline"); + + // Free allocated memory + if(linebuffer != NULL) + { + free(linebuffer); + linebuffer = NULL; + } + // Close the file fclose(fp); @@ -139,18 +171,26 @@ int countlineswith(const char* str, const char* fname) { FILE *fp; int found = 0; - char buffer[512]; + char *buffer = NULL; + size_t size = 0; if((fp = fopen(fname, "r")) == NULL) { return -1; } // Search through file - // fgets reads a string from the specified file up to either a newline character or EOF - while(fgets(buffer, sizeof(buffer), fp) != NULL) + // getline reads a string from the specified file up to either a newline character or EOF + while(getline(&buffer, &size, fp) != -1) if((strstr(buffer, str)) != NULL) found++; + // Free allocated memory + if(buffer != NULL) + { + free(buffer); + buffer = NULL; + } + // Close the file fclose(fp); diff --git a/parser.c b/parser.c index 818488f9..26721db5 100644 --- a/parser.c +++ b/parser.c @@ -134,8 +134,9 @@ void *pihole_log_thread(void *val) void process_pihole_log(int file) { int i; - char readbuffer[1024] = ""; - char readbuffer2[1024] = ""; + char *readbuffer = NULL; + char *readbuffer2 = NULL; + size_t size1 = 0, size2 = 0; FILE *fp; if(file == 0) @@ -169,18 +170,19 @@ void process_pihole_log(int file) long int fposbck = ftell(fp); // Read pihole log from current position until EOF line by line - while( fgets (readbuffer , sizeof(readbuffer)-1 , fp) != NULL ) + errno = 0; + while(getline(&readbuffer, &size1, fp) != -1) { // Ensure that the line we read ended with a newline // It can happen that we read too fast and dnsmasq didn't had the time - // to finish writing to the log. In this case, fgets() will not stop + // to finish writing to the log. In this case, getline() will not stop // at a newline character, but at EOF. If we detect this scenario, we // have to wait a little longer and re-try reading if(feof(fp)) { fseek(fp, fposbck, SEEK_SET); sleepms(10); - if(fgets (readbuffer , sizeof(readbuffer)-1 , fp) == NULL) + if(getline(&readbuffer, &size1, fp) == -1) break; } @@ -309,7 +311,7 @@ void process_pihole_log(int file) int forwardID = -1; for(i=0; i<200; i++) { - if(fgets (readbuffer2 , sizeof(readbuffer2) , fp) != NULL) + if(getline(&readbuffer2, &size2, fp) != -1) { // Process only matching lines if(strstr(readbuffer2, domainwithspaces) != NULL) @@ -367,9 +369,17 @@ void process_pihole_log(int file) } } } + // Return to previous file pointer position fseek(fp, fpos, SEEK_SET); + // Free memory allocated by readline + if(readbuffer2 != NULL) + { + free(readbuffer2); + readbuffer2 = NULL; + } + // Go through already knows domains and see if it is one of them // Check struct size memory_check(DOMAINS); @@ -595,6 +605,13 @@ void process_pihole_log(int file) } } + if(errno == ENOMEM) + logg("WARN: process_pihole_log failed: could not allocate memory for getline"); + + // Free memory allocated by readline + if(readbuffer != NULL) + free(readbuffer); + // IF we are reading the main log, we want to store the last read // position so that we can jump to this position in the next round if(file == 0) diff --git a/setupVars.c b/setupVars.c index 6718d64d..7137af38 100644 --- a/setupVars.c +++ b/setupVars.c @@ -9,7 +9,6 @@ * Please see LICENSE file for your rights under this license. */ #include "FTL.h" -#define SETUPVARSLINELENGTH 100000 char ** setupVarsArray = NULL; @@ -54,15 +53,22 @@ char * read_setupVarsconf(const char * key) return NULL; } + // Allocate keystr char * keystr = calloc(strlen(key)+2, sizeof(char)); - linebuffer = calloc(SETUPVARSLINELENGTH, sizeof(char)); - + if(keystr == NULL) + { + logg("WARN: read_setupVarsconf failed: could not allocate memory for keystr"); + fclose(setupVarsfp); + return NULL; + } sprintf(keystr, "%s=", key); - while(fgets(linebuffer, SETUPVARSLINELENGTH, setupVarsfp) != NULL) + size_t size; + errno = 0; + while(getline(&linebuffer, &size, setupVarsfp) != -1) { - // Strip newline from fgets output - linebuffer[strlen(linebuffer) - 1] = '\0'; + // Strip (possible) newline + linebuffer[strcspn(linebuffer, "\n")] = '\0'; // Skip comment lines if(linebuffer[0] == '#' || linebuffer[0] == ';') @@ -78,15 +84,22 @@ char * read_setupVarsconf(const char * key) return (find_equals(linebuffer) + 1); } + if(errno == ENOMEM) + logg("WARN: read_setupVarsconf failed: could not allocate memory for getline"); + // Key not found -> return NULL fclose(setupVarsfp); - // setting unused pointers to NULL - // protecting against dangling pointer bugs + // Freeing keystr, not setting to NULL, since not used outside of this routine free(keystr); - keystr = NULL; - free(linebuffer); - linebuffer = NULL; + + // Freeing and setting to NULL to prevent a dangling pointer + if(linebuffer != NULL) + { + free(linebuffer); + linebuffer = NULL; + } + return NULL; }