Merge pull request #230 from pi-hole/master

Git flow Pi-hole FTL v3.0
This commit is contained in:
DL6ER
2018-02-15 21:23:47 +01:00
committed by GitHub
15 changed files with 360 additions and 245 deletions
+11
View File
@@ -254,3 +254,14 @@ bool rereadgravity;
long int lastDBimportedtimestamp;
bool ipv4telnet, ipv6telnet;
bool istelnet[MAXCONNS];
// Use out own memory handling functions that will detect possible errors
// and report accordingly in the log. This will make debugging FTL crashs
// caused by insufficient memory or by code bugs (not properly dealing
// with NULL pointers) much easier.
#define free(param) FTLfree(param, __FILE__, __FUNCTION__, __LINE__)
#define lib_strdup() strdup()
#undef strdup
#define strdup(param) FTLstrdup(param, __FILE__, __FUNCTION__, __LINE__)
#define calloc(p1,p2) FTLcalloc(p1,p2, __FILE__, __FUNCTION__, __LINE__)
#define realloc(p1,p2) FTLrealloc(p1,p2, __FILE__, __FUNCTION__, __LINE__)
+1 -1
View File
@@ -9,7 +9,7 @@
# Please see LICENSE file for your rights under this license.
DEPS = FTL.h routines.h api.h version.h
OBJ = main.o structs.o log.o daemon.o parser.o signals.o socket.o request.o grep.o setupVars.o args.o flush.o threads.o gc.o config.o database.o api.o msgpack.o
OBJ = main.o memory.o log.o daemon.o parser.o signals.o socket.o request.o grep.o setupVars.o args.o flush.o threads.o gc.o config.o database.o api.o msgpack.o
# Get git commit version and date
GIT_BRANCH := $(shell git branch | sed -n 's/^\* //p')
+14 -6
View File
@@ -272,6 +272,7 @@ void getTopDomains(char *client_message, int *sock)
ssend(*sock, "%i %i %s wildcard\n", n, domains[j].blockedcount, domains[j].domain);
else {
char *fancyWildcard = calloc(3 + strlen(domains[j].domain), sizeof(char));
if(fancyWildcard == NULL) return;
sprintf(fancyWildcard, "*.%s", domains[j].domain);
if(!pack_str32(*sock, fancyWildcard))
@@ -466,10 +467,8 @@ void getForwardDestinations(char *client_message, int *sock)
// Is this the "local" forward destination?
if(j == counters.forwarded)
{
ip = calloc(4,1);
strcpy(ip, "::1");
name = calloc(6,1);
strcpy(name, "local");
ip = strdup("::1");
name = strdup("local");
if(totalqueries > 0)
// Whats the percentage of (cached + blocked) queries on the total amount of queries?
@@ -582,6 +581,7 @@ void getAllQueries(char *client_message, int *sock)
if(command(client_message, ">getallqueries-domain")) {
// Get domain name we want to see only (limit length to 255 chars)
domainname = calloc(256, sizeof(char));
if(domainname == NULL) return;
sscanf(client_message, ">getallqueries-domain %255s", domainname);
if(debugclients)
logg("Showing only queries with domain %s", domainname);
@@ -589,8 +589,9 @@ void getAllQueries(char *client_message, int *sock)
}
// Client filtering?
if(command(client_message, ">getallqueries-client")) {
clientname = calloc(256, sizeof(char));
// Get client name we want to see only (limit length to 255 chars)
clientname = calloc(256, sizeof(char));
if(clientname == NULL) return;
sscanf(client_message, ">getallqueries-client %255s", clientname);
if(debugclients)
logg("Showing only queries with client %s", clientname);
@@ -667,8 +668,10 @@ void getAllQueries(char *client_message, int *sock)
else
strcpy(qtype,"IPv6");
if((queries[i].status == 1 || queries[i].status == 4) && !showblocked)
// 1 = gravity.list, 4 = wildcard, 5 = black.list
if((queries[i].status == 1 || queries[i].status == 4 || queries[i].status == 5) && !showblocked)
continue;
// 2 = forwarded, 3 = cached
if((queries[i].status == 2 || queries[i].status == 3) && !showpermitted)
continue;
@@ -785,6 +788,7 @@ void getMemoryUsage(int *sock)
{
unsigned long int structbytes = sizeof(countersStruct) + sizeof(ConfigStruct) + counters.queries_MAX*sizeof(queriesDataStruct) + counters.forwarded_MAX*sizeof(forwardedDataStruct) + counters.clients_MAX*sizeof(clientsDataStruct) + counters.domains_MAX*sizeof(domainsDataStruct) + counters.overTime_MAX*sizeof(overTimeDataStruct) + (counters.wildcarddomains)*sizeof(*wildcarddomains);
char *structprefix = calloc(2, sizeof(char));
if(structprefix == NULL) return;
double formated = 0.0;
format_memory_size(structprefix, structbytes, &formated);
@@ -796,6 +800,7 @@ void getMemoryUsage(int *sock)
unsigned long int dynamicbytes = memory.wildcarddomains + memory.domainnames + memory.clientips + memory.clientnames + memory.forwardedips + memory.forwardednames + memory.forwarddata;
char *dynamicprefix = calloc(2, sizeof(char));
if(dynamicprefix == NULL) return;
format_memory_size(dynamicprefix, dynamicbytes, &formated);
if(istelnet[*sock])
@@ -806,6 +811,7 @@ void getMemoryUsage(int *sock)
unsigned long int totalbytes = structbytes + dynamicbytes;
char *totalprefix = calloc(2, sizeof(char));
if(totalprefix == NULL) return;
format_memory_size(totalprefix, totalbytes, &formated);
if(istelnet[*sock])
@@ -1020,6 +1026,7 @@ void getVersion(int *sock)
ssend(*sock, "version vDev-%s\ntag %s\nbranch %s\ndate %s\n", hash, tag, GIT_BRANCH, GIT_DATE);
else {
char *hashVersion = calloc(6 + strlen(hash), sizeof(char));
if(hashVersion == NULL) return;
sprintf(hashVersion, "vDev-%s", hash);
if(!pack_str32(*sock, hashVersion) ||
@@ -1048,6 +1055,7 @@ void getDBstats(int *sock)
filesize = st.st_size;
char *prefix = calloc(2, sizeof(char));
if(prefix == NULL) return;
double formated = 0.0;
format_memory_size(prefix, filesize, &formated);
+3 -4
View File
@@ -252,13 +252,12 @@ char *getUserName(void)
struct passwd *pw = getpwuid(euid);
if(pw)
{
username = calloc(strlen(pw->pw_name)+1, sizeof(char));
strcpy(username, pw->pw_name);
username = strdup(pw->pw_name);
}
else
{
username = calloc(12, sizeof(char));
sprintf(username, "%i", euid);
if(asprintf(&username, "%i", euid) < 0)
return NULL;
}
return username;
+1 -4
View File
@@ -354,10 +354,7 @@ void save_to_DB(void)
sqlite3_bind_text(stmt, 4, domains[queries[i].domainID].domain, -1, SQLITE_TRANSIENT);
// CLIENT
if(strlen(clients[queries[i].clientID].name) > 0)
sqlite3_bind_text(stmt, 5, clients[queries[i].clientID].name, -1, SQLITE_TRANSIENT);
else
sqlite3_bind_text(stmt, 5, clients[queries[i].clientID].ip, -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmt, 5, clients[queries[i].clientID].ip, -1, SQLITE_TRANSIENT);
// FORWARD
if(queries[i].status == 2 && queries[i].forwardID > -1)
+2 -1
View File
@@ -65,7 +65,8 @@ void pihole_log_flushed(bool message)
// overTime struct: Free allocated substructure
for(i=0;i<counters.overTime;i++)
{
free(overTime[i].forwarddata);
if(overTime[i].forwarddata != NULL )
free(overTime[i].forwarddata);
free(overTime[i].querytypedata);
}
free(overTime);
+1
View File
@@ -151,6 +151,7 @@ void readWildcardsList()
memory_check(WILDCARD);
// Allocate space for new domain entry and save domain
wildcarddomains[counters.wildcarddomains] = calloc(strlen(domain)+1,sizeof(char));
if(wildcarddomains[counters.wildcarddomains] == NULL) return;
memory.wildcarddomains += (strlen(domain) + 1) * sizeof(char);
strcpy(wildcarddomains[counters.wildcarddomains], domain);
+1
View File
@@ -120,6 +120,7 @@ void logg_struct_resize(const char* str, int to, int step)
unsigned long int bytes = structbytes + dynamicbytes;
char *prefix = calloc(2, sizeof(char));
if(prefix == NULL) return;
double formated = 0.0;
format_memory_size(prefix, bytes, &formated);
+297
View File
@@ -0,0 +1,297 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* FTL Engine
* Global variable definitions and memory reallocation handling
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
FTLFileNamesStruct FTLfiles = {
"/etc/pihole/pihole-FTL.conf",
"/var/log/pihole-FTL.log",
"/var/run/pihole-FTL.pid",
"/var/run/pihole-FTL.port",
NULL,
"/var/run/pihole/FTL.sock"
};
logFileNamesStruct files = {
"/var/log/pihole.log",
"/etc/pihole/list.preEventHorizon",
"/etc/pihole/whitelist.txt",
"/etc/pihole/blacklist.txt",
"/etc/pihole/setupVars.conf",
"/etc/dnsmasq.d/03-pihole-wildcard.conf",
"/etc/pihole/auditlog.list",
"/etc/dnsmasq.d/01-pihole.conf"
};
countersStruct counters = { 0 };
void memory_check(int which)
{
switch(which)
{
case QUERIES:
if(counters.queries >= counters.queries_MAX)
{
// Have to reallocate memory
counters.queries_MAX += QUERIESALLOCSTEP;
logg_struct_resize("queries",counters.queries_MAX,QUERIESALLOCSTEP);
queries = realloc(queries, counters.queries_MAX*sizeof(queriesDataStruct));
if(queries == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case FORWARDED:
if(counters.forwarded >= counters.forwarded_MAX)
{
// Have to reallocate memory
counters.forwarded_MAX += FORWARDEDALLOCSTEP;
logg_struct_resize("forwarded",counters.forwarded_MAX,FORWARDEDALLOCSTEP);
forwarded = realloc(forwarded, counters.forwarded_MAX*sizeof(forwardedDataStruct));
if(forwarded == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case CLIENTS:
if(counters.clients >= counters.clients_MAX)
{
// Have to reallocate memory
counters.clients_MAX += CLIENTSALLOCSTEP;
logg_struct_resize("clients",counters.clients_MAX,CLIENTSALLOCSTEP);
clients = realloc(clients, counters.clients_MAX*sizeof(clientsDataStruct));
if(clients == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case DOMAINS:
if(counters.domains >= counters.domains_MAX)
{
// Have to reallocate memory
counters.domains_MAX += DOMAINSALLOCSTEP;
logg_struct_resize("domains",counters.domains_MAX,DOMAINSALLOCSTEP);
domains = realloc(domains, counters.domains_MAX*sizeof(domainsDataStruct));
if(domains == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case OVERTIME:
if(counters.overTime >= counters.overTime_MAX)
{
// Have to reallocate memory
counters.overTime_MAX += OVERTIMEALLOCSTEP;
logg_struct_resize("overTime",counters.overTime_MAX,OVERTIMEALLOCSTEP);
overTime = realloc(overTime, counters.overTime_MAX*sizeof(overTimeDataStruct));
if(overTime == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case WILDCARD:
// Definitely enlarge wildcard entry
// Enlarge wildcarddomains pointer array
logg_struct_resize("wildcards", (counters.wildcarddomains+1), 1);
wildcarddomains = realloc(wildcarddomains, (counters.wildcarddomains+1)*sizeof(*wildcarddomains));
if(wildcarddomains == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
break;
default:
/* That cannot happen */
logg("Fatal error in memory_check(%i)", which);
exit(EXIT_FAILURE);
break;
}
}
void validate_access(const char * name, int pos, bool testmagic, int line, const char * function, const char * file)
{
int limit = 0;
if(name[0] == 'c') limit = counters.clients_MAX;
else if(name[0] == 'd') limit = counters.domains_MAX;
else if(name[0] == 'q') limit = counters.queries_MAX;
else if(name[0] == 'o') limit = counters.overTime_MAX;
else if(name[0] == 'f') limit = counters.forwarded_MAX;
else if(name[0] == 'w') limit = counters.wildcarddomains;
else { logg("Validator error (range)"); killed = 1; }
if(pos >= limit || pos < 0)
{
logg("FATAL ERROR: Trying to access %s[%i], but maximum is %i", name, pos, limit);
logg(" found in %s() (%s:%i)", function, file, line);
}
// Don't test magic byte if detected potential out-of-bounds error
else if(testmagic)
{
unsigned char magic = 0x00;
if(name[0] == 'c') magic = clients[pos].magic;
else if(name[0] == 'd') magic = domains[pos].magic;
else if(name[0] == 'q') magic = queries[pos].magic;
else if(name[0] == 'o') magic = overTime[pos].magic;
else if(name[0] == 'f') magic = forwarded[pos].magic;
else { logg("Validator error (magic byte)"); killed = 1; }
if(magic != MAGICBYTE)
{
logg("FATAL ERROR: Trying to access %s[%i], but magic byte is %x", name, pos, magic);
logg(" found in %s() (%s:%i)", function, file, line);
}
}
}
void validate_access_oTfd(int timeidx, int forwardID, int line, const char * function, const char * file)
{
// Determine if there is enough space for saving the current
// forwardID in the overTime data structure, allocate space otherwise
validate_access("overTime", timeidx, true, __LINE__, __FUNCTION__, __FILE__);
if(overTime[timeidx].forwardnum <= forwardID)
{
// Reallocate more space for forwarddata
overTime[timeidx].forwarddata = realloc(overTime[timeidx].forwarddata, (forwardID+1)*sizeof(*overTime[timeidx].forwarddata));
// Initialize new data fields with zeroes
int j;
for(j = overTime[timeidx].forwardnum; j <= forwardID; j++)
{
overTime[timeidx].forwarddata[j] = 0;
memory.forwarddata++;
}
// Update counter
overTime[timeidx].forwardnum = forwardID + 1;
}
int limit = overTime[timeidx].forwardnum;
if(forwardID >= limit || forwardID < 0)
{
logg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
logg("FATAL ERROR: Trying to access overTime.forwarddata[%i], but maximum is %i", forwardID, limit);
logg(" found in %s() (%s:%i)", function, file, line);
}
}
void validate_access_oTcl(int timeidx, int clientID, int line, const char * function, const char * file)
{
// Determine if there is enough space for saving the current
// clientID in the overTime data structure, allocate space otherwise
if(overTime[timeidx].clientnum <= clientID)
{
// Reallocate more space for clientdata
overTime[timeidx].clientdata = realloc(overTime[timeidx].clientdata, (clientID+1)*sizeof(*overTime[timeidx].clientdata));
// Initialize new data fields with zeroes
int i;
for(i = overTime[timeidx].clientnum; i <= clientID; i++)
{
overTime[timeidx].clientdata[i] = 0;
memory.clientdata++;
}
// Update counter
overTime[timeidx].clientnum = clientID + 1;
}
int limit = overTime[timeidx].clientnum;
if(clientID >= limit || clientID < 0)
{
logg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
logg("FATAL ERROR: Trying to access overTime.clientdata[%i], but maximum is %i", clientID, limit);
logg(" found in %s() (%s:%i)", function, file, line);
}
}
// The special memory handling routines have to be the last ones in this source file
// as we restore the original definition of the strdup, free, calloc, and realloc
// functions in here, i.e. if anything extra would come below these lines, it would
// not be protected by our (error logging) functions!
#undef strdup
char *FTLstrdup(const char *src, const char * file, const char * function, int line)
{
// The FTLstrdup() function returns a pointer to a new string which is a
// duplicate of the string s. Memory for the new string is obtained with
// calloc(3), and can be freed with free(3).
if(src == NULL)
{
logg("WARN: Trying to copy a NULL string in %s() (%s:%i)", function, file, line);
return NULL;
}
size_t len = strlen(src);
char *dest = calloc(len+1, sizeof(char));
if(dest == NULL)
{
logg("FATAL: Memory allocation failed in %s() (%s:%i)", function, file, line);
return NULL;
}
// Use memcpy as memory areas cannot overlap
memcpy(dest, src, len);
dest[len] = '\0';
return dest;
}
#undef calloc
void *FTLcalloc(size_t nmemb, size_t size, const char * file, const char * function, int line)
{
// The FTLcalloc() function allocates memory for an array of nmemb elements
// of size bytes each and returns a pointer to the allocated memory. The
// memory is set to zero. If nmemb or size is 0, then calloc() returns
// either NULL, or a unique pointer value that can later be successfully
// passed to free().
void *ptr = calloc(nmemb, size);
if(ptr == NULL)
logg("FATAL: Memory allocation (%u x %u) failed in %s() (%s:%i)",
nmemb, size, function, file, line);
return ptr;
}
#undef realloc
void *FTLrealloc(void *ptr_in, size_t size, const char * file, const char * function, int line)
{
// The FTLrealloc() function changes the size of the memory block pointed to
// by ptr to size bytes. The contents will be unchanged in the range from
// the start of the region up to the minimum of the old and new sizes. If
// the new size is larger than the old size, the added memory will not be
// initialized. If ptr is NULL, then the call is equivalent to malloc(size),
// for all values of size; if size is equal to zero, and ptr is
// not NULL, then the call is equivalent to free(ptr). Unless ptr is
// NULL, it must have been returned by an earlier call to malloc(), cal‐
// loc() or realloc(). If the area pointed to was moved, a free(ptr) is
// done.
void *ptr_out = realloc(ptr_in, size);
if(ptr_out == NULL)
logg("FATAL: Memory reallocation (%p -> %u) failed in %s() (%s:%i)",
ptr_in, size, function, file, line);
return ptr_out;
}
#undef free
void FTLfree(void *ptr, const char * file, const char * function, int line)
{
// The free() function frees the memory space pointed to by ptr, which
// must have been returned by a previous call to malloc(), calloc(), or
// realloc(). Otherwise, or if free(ptr) has already been called before,
// undefined behavior occurs. If ptr is NULL, no operation is performed.
if(ptr == NULL)
logg("FATAL: Trying to free NULL pointer in %s() (%s:%i)", function, file, line);
// We intentionally run free() nevertheless to see the crash in the debugger
free(ptr);
}
+1 -1
View File
@@ -96,7 +96,7 @@ bool pack_str32(int sock, char *string) {
// Make sure that the length is less than 4294967296
size_t length = strlen(string);
if(length >= 2147483648) {
if(length >= 2147483648u) {
logg("Tried to send a str32 longer than 2147483647 bytes!");
return false;
}
+9 -95
View File
@@ -328,6 +328,7 @@ void process_pihole_log(void)
}
char *domain = calloc(domainlen+1,sizeof(char));
if(domain == NULL) continue;
// strncat() NULL-terminates the copied string (strncpy() doesn't!)
strncat(domain,domainstart+2,domainlen);
// Convert domain to lower case
@@ -363,6 +364,7 @@ void process_pihole_log(void)
}
char *client = calloc(clientlen+1,sizeof(char));
if(client == NULL){ free(domain); continue; }
// strncat() NULL-terminates the copied string (strncpy() doesn't!)
strncat(client,domainend+6,clientlen);
// Convert client to lower case
@@ -525,6 +527,7 @@ void process_pihole_log(void)
}
char *forward = calloc(forwardlen+1,sizeof(char));
if(forward == NULL) continue;
// strncat() NULL-terminates the copied string (strncpy() doesn't!)
strncat(forward,forwardstart+4,forwardlen);
// Convert forward to lower case
@@ -970,13 +973,14 @@ char *resolveHostname(const char *addr)
if(he == NULL)
{
// No hostname found
hostname = calloc(1,sizeof(char));
hostname[0] = '\0';
hostname = strdup("");
if(hostname == NULL) return NULL;
}
else
{
// Return hostname copied to new memory location
hostname = strdup(he->h_name);
if(hostname == NULL) return NULL;
// Convert hostname to lower case
strtolower(hostname);
}
@@ -1184,7 +1188,7 @@ int findDomainID(const char *domain)
domains[domainID].blockedcount = 0;
// Initialize wildcard blocking flag with false
domains[domainID].wildcard = false;
// Store domain name
// Store domain name - no need to check for NULL here as it doesn't harm
domains[domainID].domain = strdup(domain);
memory.domainnames += (strlen(domain) + 1) * sizeof(char);
// Store DNSSEC result for this domain
@@ -1269,10 +1273,10 @@ int findClientID(const char *client)
clients[clientID].magic = MAGICBYTE;
// Set its counter to 1
clients[clientID].count = 1;
// Store client IP
// Store client IP - no need to check for NULL here as it doesn't harm
clients[clientID].ip = strdup(client);
memory.clientips += (strlen(client) + 1) * sizeof(char);
// Store client hostname
// Store client hostname - no need to check for NULL here as it doesn't harm
clients[clientID].name = strdup(hostname);
memory.clientnames += (strlen(hostname) + 1) * sizeof(char);
free(hostname);
@@ -1282,96 +1286,6 @@ int findClientID(const char *client)
return clientID;
}
void validate_access(const char * name, int pos, bool testmagic, int line, const char * function, const char * file)
{
int limit = 0;
if(name[0] == 'c') limit = counters.clients_MAX;
else if(name[0] == 'd') limit = counters.domains_MAX;
else if(name[0] == 'q') limit = counters.queries_MAX;
else if(name[0] == 'o') limit = counters.overTime_MAX;
else if(name[0] == 'f') limit = counters.forwarded_MAX;
else if(name[0] == 'w') limit = counters.wildcarddomains;
else { logg("Validator error (range)"); killed = 1; }
if(pos >= limit || pos < 0)
{
logg("FATAL ERROR: Trying to access %s[%i], but maximum is %i", name, pos, limit);
logg(" found in %s() (line %i) in %s", function, line, file);
}
// Don't test magic byte if detected potential out-of-bounds error
else if(testmagic)
{
unsigned char magic = 0x00;
if(name[0] == 'c') magic = clients[pos].magic;
else if(name[0] == 'd') magic = domains[pos].magic;
else if(name[0] == 'q') magic = queries[pos].magic;
else if(name[0] == 'o') magic = overTime[pos].magic;
else if(name[0] == 'f') magic = forwarded[pos].magic;
else { logg("Validator error (magic byte)"); killed = 1; }
if(magic != MAGICBYTE)
{
logg("FATAL ERROR: Trying to access %s[%i], but magic byte is %x", name, pos, magic);
logg(" found in %s() (line %i) in %s", function, line, file);
}
}
}
void validate_access_oTfd(int timeidx, int forwardID, int line, const char * function, const char * file)
{
// Determine if there is enough space for saving the current
// forwardID in the overTime data structure, allocate space otherwise
validate_access("overTime", timeidx, true, __LINE__, __FUNCTION__, __FILE__);
if(overTime[timeidx].forwardnum <= forwardID)
{
// Reallocate more space for forwarddata
overTime[timeidx].forwarddata = realloc(overTime[timeidx].forwarddata, (forwardID+1)*sizeof(*overTime[timeidx].forwarddata));
// Initialize new data fields with zeroes
int j;
for(j = overTime[timeidx].forwardnum; j <= forwardID; j++)
{
overTime[timeidx].forwarddata[j] = 0;
memory.forwarddata++;
}
// Update counter
overTime[timeidx].forwardnum = forwardID + 1;
}
int limit = overTime[timeidx].forwardnum;
if(forwardID >= limit || forwardID < 0)
{
logg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
logg("FATAL ERROR: Trying to access overTime.forwarddata[%i], but maximum is %i", forwardID, limit);
logg(" found in %s() (line %i) in %s", function, line, file);
}
}
void validate_access_oTcl(int timeidx, int clientID, int line, const char * function, const char * file)
{
// Determine if there is enough space for saving the current
// clientID in the overTime data structure, allocate space otherwise
if(overTime[timeidx].clientnum <= clientID)
{
// Reallocate more space for clientdata
overTime[timeidx].clientdata = realloc(overTime[timeidx].clientdata, (clientID+1)*sizeof(*overTime[timeidx].clientdata));
// Initialize new data fields with zeroes
int i;
for(i = overTime[timeidx].clientnum; i <= clientID; i++)
{
overTime[timeidx].clientdata[i] = 0;
memory.clientdata++;
}
// Update counter
overTime[timeidx].clientnum = clientID + 1;
}
int limit = overTime[timeidx].clientnum;
if(clientID >= limit || clientID < 0)
{
logg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
logg("FATAL ERROR: Trying to access overTime.clientdata[%i], but maximum is %i", clientID, limit);
logg(" found in %s() (line %i) in %s", function, line, file);
}
}
void reresolveHostnames(void)
{
int clientID;
+9 -3
View File
@@ -29,9 +29,6 @@ void open_pihole_log(void);
void handle_signals(void);
void process_pihole_log(void);
void *pihole_log_thread(void *val);
void validate_access(const char * name, int pos, bool testmagic, int line, const char * function, const char * file);
void validate_access_oTfd(int timeidx, int forwardID, int line, const char * function, const char * file);
void validate_access_oTcl(int timeidx, int clientID, int line, const char * function, const char * file);
void reresolveHostnames(void);
int findClientID(const char *client);
int findDomainID(const char *domain);
@@ -88,3 +85,12 @@ void *DB_thread(void *val);
int get_number_of_queries_in_DB(void);
void save_to_DB(void);
void read_data_from_DB(void);
// memory.c
char *FTLstrdup(const char *src, const char *file, const char *function, int line);
void *FTLcalloc(size_t nmemb, size_t size, const char *file, const char *function, int line);
void *FTLrealloc(void *ptr_in, size_t size, const char *file, const char *function, int line);
void FTLfree(void *ptr, const char* file, const char *function, int line);
void validate_access(const char * name, int pos, bool testmagic, int line, const char * function, const char * file);
void validate_access_oTfd(int timeidx, int forwardID, int line, const char * function, const char * file);
void validate_access_oTcl(int timeidx, int clientID, int line, const char * function, const char * file);
+3
View File
@@ -119,12 +119,14 @@ void getSetupVarsArray(char * input)
while (p) {
setupVarsArray = realloc(setupVarsArray, sizeof(char*) * ++setupVarsElements);
if(setupVarsArray == NULL) return;
setupVarsArray[setupVarsElements-1] = p;
p = strtok(NULL, ",");
}
/* realloc one extra element for the last NULL */
setupVarsArray = realloc(setupVarsArray, sizeof(char*) * (setupVarsElements+1));
if(setupVarsArray == NULL) return;
setupVarsArray[setupVarsElements] = NULL;
}
@@ -168,6 +170,7 @@ bool insetupVarsArray(char * str)
// Copying strlen-1 chars into buffer of size strlen: OK
size_t lenght = strlen(setupVarsArray[i]);
char * domain = calloc(lenght, sizeof(char));
if(domain == NULL) return false;
// strncat() NULL-terminates the copied string (strncpy() doesn't!)
strncat(domain, setupVarsArray[i]+1, lenght-1);
+7 -4
View File
@@ -317,8 +317,8 @@ void *telnet_connection_handler_thread(void *socket_desc)
{
if (n > 0)
{
char *message = calloc(strlen(client_message)+1,sizeof(char));
strcpy(message, client_message);
char *message = strdup(client_message);
if(message == NULL) break;
// Clear client message receive buffer
memset(client_message, 0, sizeof client_message);
@@ -377,8 +377,8 @@ void *socket_connection_handler_thread(void *socket_desc)
{
if (n > 0)
{
char *message = calloc(strlen(client_message)+1,sizeof(char));
strcpy(message, client_message);
char *message = strdup(client_message);
if(message == NULL) break;
// Clear client message receive buffer
memset(client_message, 0, sizeof client_message);
@@ -460,6 +460,7 @@ void *telnet_listening_thread_IPv4(void *args)
// Allocate memory used to transport client socket ID to client listening thread
int *newsock;
newsock = calloc(1,sizeof(int));
if(newsock == NULL) break;
*newsock = csck;
pthread_t telnet_connection_thread;
@@ -500,6 +501,7 @@ void *telnet_listening_thread_IPv6(void *args)
// Allocate memory used to transport client socket ID to client listening thread
int *newsock;
newsock = calloc(1,sizeof(int));
if(newsock == NULL) break;
*newsock = csck;
pthread_t telnet_connection_thread;
@@ -536,6 +538,7 @@ void *socket_listening_thread(void *args)
// Allocate memory used to transport client socket ID to client listening thread
int *newsock;
newsock = calloc(1,sizeof(int));
if(newsock == NULL) break;
*newsock = csck;
pthread_t socket_connection_thread;
-126
View File
@@ -1,126 +0,0 @@
/* Pi-hole: A black hole for Internet advertisements
* (c) 2017 Pi-hole, LLC (https://pi-hole.net)
* Network-wide ad blocking via your own hardware.
*
* FTL Engine
* Global variable definitions and memory reallocation handling
*
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
#include "FTL.h"
FTLFileNamesStruct FTLfiles = {
"/etc/pihole/pihole-FTL.conf",
"/var/log/pihole-FTL.log",
"/var/run/pihole-FTL.pid",
"/var/run/pihole-FTL.port",
NULL,
"/var/run/pihole/FTL.sock"
};
logFileNamesStruct files = {
"/var/log/pihole.log",
"/etc/pihole/list.preEventHorizon",
"/etc/pihole/whitelist.txt",
"/etc/pihole/blacklist.txt",
"/etc/pihole/setupVars.conf",
"/etc/dnsmasq.d/03-pihole-wildcard.conf",
"/etc/pihole/auditlog.list",
"/etc/dnsmasq.d/01-pihole.conf"
};
countersStruct counters = { 0 };
void memory_check(int which)
{
switch(which)
{
case QUERIES:
if(counters.queries >= counters.queries_MAX)
{
// Have to reallocate memory
counters.queries_MAX += QUERIESALLOCSTEP;
logg_struct_resize("queries",counters.queries_MAX,QUERIESALLOCSTEP);
queries = realloc(queries, counters.queries_MAX*sizeof(queriesDataStruct));
if(queries == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case FORWARDED:
if(counters.forwarded >= counters.forwarded_MAX)
{
// Have to reallocate memory
counters.forwarded_MAX += FORWARDEDALLOCSTEP;
logg_struct_resize("forwarded",counters.forwarded_MAX,FORWARDEDALLOCSTEP);
forwarded = realloc(forwarded, counters.forwarded_MAX*sizeof(forwardedDataStruct));
if(forwarded == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case CLIENTS:
if(counters.clients >= counters.clients_MAX)
{
// Have to reallocate memory
counters.clients_MAX += CLIENTSALLOCSTEP;
logg_struct_resize("clients",counters.clients_MAX,CLIENTSALLOCSTEP);
clients = realloc(clients, counters.clients_MAX*sizeof(clientsDataStruct));
if(clients == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case DOMAINS:
if(counters.domains >= counters.domains_MAX)
{
// Have to reallocate memory
counters.domains_MAX += DOMAINSALLOCSTEP;
logg_struct_resize("domains",counters.domains_MAX,DOMAINSALLOCSTEP);
domains = realloc(domains, counters.domains_MAX*sizeof(domainsDataStruct));
if(domains == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case OVERTIME:
if(counters.overTime >= counters.overTime_MAX)
{
// Have to reallocate memory
counters.overTime_MAX += OVERTIMEALLOCSTEP;
logg_struct_resize("overTime",counters.overTime_MAX,OVERTIMEALLOCSTEP);
overTime = realloc(overTime, counters.overTime_MAX*sizeof(overTimeDataStruct));
if(overTime == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
}
break;
case WILDCARD:
// Definitely enlarge wildcard entry
// Enlarge wildcarddomains pointer array
logg_struct_resize("wildcards", (counters.wildcarddomains+1), 1);
wildcarddomains = realloc(wildcarddomains, (counters.wildcarddomains+1)*sizeof(*wildcarddomains));
if(wildcarddomains == NULL)
{
logg("FATAL: Memory allocation failed! Exiting");
exit(EXIT_FAILURE);
}
break;
default:
/* That cannot happen */
logg("Fatal error in memory_check(%i)", which);
exit(EXIT_FAILURE);
break;
}
}