From 32be41ed5d414bc001f6f217d5a8ce73b77ec4c2 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Fri, 8 Mar 2019 11:12:41 +0100 Subject: [PATCH] Declare attributes for functions in FTL. These attributes help the compiler to optimize functions calls and to check our code more carefully during compilation. See pull reqeust text for details. Signed-off-by: DL6ER --- Makefile | 4 +++- api.c | 14 +++++++------- config.c | 2 +- database.c | 14 +++++++------- dnsmasq_interface.c | 4 ++-- gc.c | 2 +- log.c | 2 +- memory.c | 6 +++--- msgpack.c | 2 +- overTime.c | 12 ++++++------ regex.c | 2 +- request.c | 2 +- routines.h | 14 +++++++------- setupVars.c | 4 ++-- shmem.c | 2 +- signals.c | 2 +- socket.c | 2 +- 17 files changed, 46 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 68347074..0ab69f31 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,9 @@ WARNFLAGS=-Wall -Wextra -Wno-unused-parameter # -Wformat-nonliteral: If -Wformat is specified, also warn if the format string is not a string literal and so cannot be checked, unless the format function takes its format arguments as a va_list. # -Wuninitialized: Warn if an automatic variable is used without first being initialized # -Wswitch-enum: Warn whenever a switch statement has an index of enumerated type and lacks a case for one or more of the named codes of that enumeration. -EXTRAWARN=-Werror -Waddress -Wlogical-op -Wmissing-field-initializers -Woverlength-strings -Wformat -Wformat-nonliteral -Wuninitialized -Wswitch-enum +# ATTRIBUTEWARNINGS: Warn for cases where adding an attribute may be beneficial. +ATTRIBUTEWARNINGS= -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wmissing-noreturn -Wsuggest-attribute=malloc -Wsuggest-attribute=format -Wmissing-format-attribute -Wsuggest-attribute=cold +EXTRAWARN=-Werror -Waddress -Wlogical-op -Wmissing-field-initializers -Woverlength-strings -Wformat -Wformat-nonliteral -Wuninitialized -Wswitch-enum $(ATTRIBUTEWARNINGS) # -FILE_OFFSET_BITS=64: used by stat(). Avoids problems with files > 2 GB on 32bit machines CCFLAGS=-std=gnu11 -I$(IDIR) $(WARNFLAGS) -D_FILE_OFFSET_BITS=64 $(HARDENING_FLAGS) $(DEBUG_FLAGS) $(CFLAGS) $(SQLITEFLAGS) # for FTL we need the pthread library diff --git a/api.c b/api.c index b5e87f03..02d123c2 100644 --- a/api.c +++ b/api.c @@ -17,7 +17,7 @@ #define min(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) /* qsort comparision function (count field), sort ASC */ -int cmpasc(const void *a, const void *b) +static int __attribute__((pure)) cmpasc(const void *a, const void *b) { int *elem1 = (int*)a; int *elem2 = (int*)b; @@ -31,7 +31,7 @@ int cmpasc(const void *a, const void *b) } // qsort subroutine, sort DESC -int cmpdesc(const void *a, const void *b) +static int __attribute__((pure)) cmpdesc(const void *a, const void *b) { int *elem1 = (int*)a; int *elem2 = (int*)b; @@ -147,7 +147,7 @@ void getOverTime(int *sock) { for(i = from; i < until; i++) { - ssend(*sock,"%i %i %i\n",overTime[i].timestamp,overTime[i].total,overTime[i].blocked); + ssend(*sock,"%li %i %i\n",overTime[i].timestamp,overTime[i].total,overTime[i].blocked); } } else @@ -812,7 +812,7 @@ void getAllQueries(char *client_message, int *sock) if(istelnet[*sock]) { - ssend(*sock,"%i %s %s %s %i %i %i %lu\n",queries[i].timestamp,qtype,domain,client,queries[i].status,queries[i].dnssec,queries[i].reply,delay); + ssend(*sock,"%li %s %s %s %i %i %i %lu\n",queries[i].timestamp,qtype,domain,client,queries[i].status,queries[i].dnssec,queries[i].reply,delay); } else { @@ -926,7 +926,7 @@ void getQueryTypesOverTime(int *sock) } if(istelnet[*sock]) - ssend(*sock, "%i %.2f %.2f\n", overTime[i].timestamp, percentageIPv4, percentageIPv6); + ssend(*sock, "%li %.2f %.2f\n", overTime[i].timestamp, percentageIPv4, percentageIPv6); else { pack_int32(*sock, overTime[i].timestamp); pack_float(*sock, percentageIPv4); @@ -1069,7 +1069,7 @@ void getClientsOverTime(int *sock) for(i = sendit; i < until; i++) { if(istelnet[*sock]) - ssend(*sock, "%i", overTime[i].timestamp); + ssend(*sock, "%li", overTime[i].timestamp); else pack_int32(*sock, overTime[i].timestamp); @@ -1180,7 +1180,7 @@ void getUnknownQueries(int *sock) char *client = getstr(clients[queries[i].clientID].ippos); if(istelnet[*sock]) - ssend(*sock, "%i %i %i %s %s %s %i %s\n", queries[i].timestamp, i, queries[i].id, type, getstr(domains[queries[i].domainID].domainpos), client, queries[i].status, queries[i].complete ? "true" : "false"); + ssend(*sock, "%li %i %i %s %s %s %i %s\n", queries[i].timestamp, i, queries[i].id, type, getstr(domains[queries[i].domainID].domainpos), client, queries[i].status, queries[i].complete ? "true" : "false"); else { pack_int32(*sock, queries[i].timestamp); pack_int32(*sock, queries[i].id); diff --git a/config.c b/config.c index 500806cc..108c743b 100644 --- a/config.c +++ b/config.c @@ -112,7 +112,7 @@ void read_FTLconf(void) config.maxDBdays = value; if(config.maxDBdays == 0) - logg(" MAXDBDAYS: --- (DB disabled)", config.maxDBdays); + logg(" MAXDBDAYS: --- (DB disabled)"); else logg(" MAXDBDAYS: max age for stored queries is %i days", config.maxDBdays); diff --git a/database.c b/database.c index 7488b2b8..89fe0dc8 100644 --- a/database.c +++ b/database.c @@ -681,7 +681,7 @@ void read_data_from_DB(void) return; } // Log DB query string in debug mode - if(config.debug & DEBUG_DATABASE) logg(rstr); + if(config.debug & DEBUG_DATABASE) logg("%s", rstr); // Prepare SQLite3 statement sqlite3_stmt* stmt; @@ -701,12 +701,12 @@ void read_data_from_DB(void) // 1483228800 = 01/01/2017 @ 12:00am (UTC) if(queryTimeStamp < 1483228800) { - logg("DB warn: TIMESTAMP should be larger than 01/01/2017 but is %i", queryTimeStamp); + logg("DB warn: TIMESTAMP should be larger than 01/01/2017 but is %li", queryTimeStamp); continue; } if(queryTimeStamp > now) { - if(config.debug & DEBUG_DATABASE) logg("DB warn: Skipping query logged in the future (%i)", queryTimeStamp); + if(config.debug & DEBUG_DATABASE) logg("DB warn: Skipping query logged in the future (%li)", queryTimeStamp); continue; } @@ -733,14 +733,14 @@ void read_data_from_DB(void) const char * domain = (const char *)sqlite3_column_text(stmt, 4); if(domain == NULL) { - logg("DB warn: DOMAIN should never be NULL, %i", queryTimeStamp); + logg("DB warn: DOMAIN should never be NULL, %li", queryTimeStamp); continue; } const char * client = (const char *)sqlite3_column_text(stmt, 5); if(client == NULL) { - logg("DB warn: CLIENT should never be NULL, %i", queryTimeStamp); + logg("DB warn: CLIENT should never be NULL, %li", queryTimeStamp); continue; } @@ -759,7 +759,7 @@ void read_data_from_DB(void) { if(forwarddest == NULL) { - logg("DB warn: FORWARD should not be NULL with status QUERY_FORWARDED, %i", queryTimeStamp); + logg("DB warn: FORWARD should not be NULL with status QUERY_FORWARDED, %li", queryTimeStamp); continue; } forwardID = findForwardID(forwarddest, true); @@ -846,7 +846,7 @@ void read_data_from_DB(void) default: logg("Error: Found unknown status %i in long term database!", status); - logg(" Timestamp: %i", queryTimeStamp); + logg(" Timestamp: %li", queryTimeStamp); logg(" Continuing anyway..."); break; } diff --git a/dnsmasq_interface.c b/dnsmasq_interface.c index d11d1de9..6972f1c6 100644 --- a/dnsmasq_interface.c +++ b/dnsmasq_interface.c @@ -16,7 +16,7 @@ void print_flags(unsigned int flags); void save_reply_type(unsigned int flags, int queryID, struct timeval response); -unsigned long converttimeval(struct timeval time); +static unsigned long converttimeval(struct timeval time) __attribute__((const)); static void block_single_domain_regex(char *domain); static void detect_blocked_IP(unsigned short flags, char* answer, int queryID); static void query_externally_blocked(int i); @@ -1076,7 +1076,7 @@ void _FTL_forwarding_failed(struct server *server, const char* file, const int l return; } -unsigned long converttimeval(struct timeval time) +static unsigned long __attribute__((const)) converttimeval(struct timeval time) { // Convert time from struct timeval into units // of 10*milliseconds diff --git a/gc.c b/gc.c index b9857f97..9713ac01 100644 --- a/gc.c +++ b/gc.c @@ -46,7 +46,7 @@ void *GC_thread(void *val) long int i; int removed = 0; - if(config.debug & DEBUG_GC) logg("GC starting, mintime: %u %s", mintime, ctime(&mintime)); + if(config.debug & DEBUG_GC) logg("GC starting, mintime: %lu %s", mintime, ctime(&mintime)); // Process all queries for(i=0; i < counters->queries; i++) diff --git a/log.c b/log.c index d1bf7b17..5c34a6d5 100644 --- a/log.c +++ b/log.c @@ -61,7 +61,7 @@ void get_timestr(char *timestring) sprintf(timestring,"%d-%02d-%02d %02d:%02d:%02d.%03i", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, millisec); } -void logg(const char *format, ...) +void __attribute__ ((format (gnu_printf, 1, 2))) logg(const char *format, ...) { char timestring[32] = ""; va_list args; diff --git a/memory.c b/memory.c index b57dccef..898eb782 100644 --- a/memory.c +++ b/memory.c @@ -166,7 +166,7 @@ char *FTLstrdup(const char *src, const char * file, const char * function, int l } #undef calloc -void *FTLcalloc(size_t nmemb, size_t size, const char * file, const char * function, int line) +void* __attribute__((malloc)) 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 @@ -175,7 +175,7 @@ void *FTLcalloc(size_t nmemb, size_t size, const char * file, const char * funct // passed to free(). void *ptr = calloc(nmemb, size); if(ptr == NULL) - logg("FATAL: Memory allocation (%u x %u) failed in %s() (%s:%i)", + logg("FATAL: Memory allocation (%zu x %zu) failed in %s() (%s:%i)", nmemb, size, function, file, line); return ptr; @@ -196,7 +196,7 @@ void *FTLrealloc(void *ptr_in, size_t size, const char * file, const char * func // done. void *ptr_out = realloc(ptr_in, size); if(ptr_out == NULL) - logg("FATAL: Memory reallocation (%p -> %u) failed in %s() (%s:%i)", + logg("FATAL: Memory reallocation (%p -> %zu) failed in %s() (%s:%i)", ptr_in, size, function, file, line); return ptr_out; diff --git a/msgpack.c b/msgpack.c index 0f512234..536749e8 100644 --- a/msgpack.c +++ b/msgpack.c @@ -22,7 +22,7 @@ void pack_basic(int sock, uint8_t format, void *value, size_t size) { swrite(sock, value, size); } -uint64_t leToBe64(uint64_t value) { +static uint64_t __attribute__((const)) leToBe64(uint64_t value) { char *ptr = (char *) &value; uint32_t part1, part2; diff --git a/overTime.c b/overTime.c index 29ab2ee6..207d0964 100644 --- a/overTime.c +++ b/overTime.c @@ -20,7 +20,7 @@ static void initSlot(unsigned int index, time_t timestamp) { // Possible debug printing if(config.debug & DEBUG_OVERTIME) - logg("initSlot(%u, %u): Zeroing overTIme slot", index, timestamp); + logg("initSlot(%u, %lu): Zeroing overTime slot", index, timestamp); overTime[index].magic = MAGICBYTE; overTime[index].timestamp = timestamp; @@ -48,7 +48,7 @@ void initOverTime(void) time_t timestamp = now - now % 3600 + 3600 - (OVERTIME_INTERVAL / 2); if(config.debug & DEBUG_OVERTIME) - logg("initOverTime(): Initializing %i slots from %u to %u", OVERTIME_SLOTS, timestamp-OVERTIME_SLOTS*OVERTIME_INTERVAL, timestamp); + logg("initOverTime(): Initializing %i slots from %lu to %lu", OVERTIME_SLOTS, timestamp-OVERTIME_SLOTS*OVERTIME_INTERVAL, timestamp); // Iterate over overTime and initialize it for(int i = OVERTIME_SLOTS-1; i >= 0 ; i--) @@ -75,19 +75,19 @@ unsigned int getOverTimeID(time_t timestamp) // Check bounds manually if(id < 0) { - logg("WARN: getOverTimeID(%u): %u is negative: %u", timestamp, id, firstTimestamp); + logg("WARN: getOverTimeID(%lu): %u is negative: %lu", timestamp, id, firstTimestamp); // Return first timestamp in case negative timestamp was determined return 0; } else if(id > OVERTIME_SLOTS-1) { - logg("WARN: getOverTimeID(%u): %i is too large: %u", timestamp, id, firstTimestamp); + logg("WARN: getOverTimeID(%lu): %i is too large: %lu", timestamp, id, firstTimestamp); // Return last timestamp in case a too large timestamp was determined return OVERTIME_SLOTS-1; } if(config.debug & DEBUG_OVERTIME) - logg("getOverTimeID(%u): %i", timestamp, id); + logg("getOverTimeID(%lu): %i", timestamp, id); return (unsigned int) id; } @@ -111,7 +111,7 @@ void moveOverTimeMemory(time_t mintime) unsigned int remainingSlots = OVERTIME_SLOTS - moveOverTime; if(config.debug & DEBUG_OVERTIME) - logg("moveOverTimeMemory(): IS: %u, SHOULD: %u, MOVING: %u", oldestOverTimeIS, oldestOverTimeSHOULD, moveOverTime); + logg("moveOverTimeMemory(): IS: %lu, SHOULD: %lu, MOVING: %u", oldestOverTimeIS, oldestOverTimeSHOULD, moveOverTime); // Check if the move over amount is valid. This prevents errors if the // function is called before GC is necessary. diff --git a/regex.c b/regex.c index 93988740..cfcbdd01 100644 --- a/regex.c +++ b/regex.c @@ -47,7 +47,7 @@ static bool init_regex(const char *regexin, int index) return true; } -bool in_whitelist(char *domain) +bool __attribute__((pure)) in_whitelist(char *domain) { bool found = false; for(int i=0; i < whitelist.count; i++) diff --git a/request.c b/request.c index 0245cbb9..74423e77 100644 --- a/request.c +++ b/request.c @@ -12,7 +12,7 @@ #include "api.h" #include "shmem.h" -bool command(char *client_message, const char* cmd) { +bool __attribute__((pure)) command(char *client_message, const char* cmd) { return strstr(client_message, cmd) != NULL; } diff --git a/routines.h b/routines.h index b97d7676..e9ac64d7 100644 --- a/routines.h +++ b/routines.h @@ -17,7 +17,7 @@ char * getUserName(void); void removepid(void); void open_FTL_log(bool test); -void logg(const char* format, ...); +void logg(const char* format, ...) __attribute__ ((format (gnu_printf, 1, 2))); void logg_struct_resize(const char* str, int to, int step); void log_counter_info(void); void format_memory_size(char *prefix, unsigned long int bytes, double *formated); @@ -37,7 +37,7 @@ char *getClientNameString(int queryID); void close_telnet_socket(void); void close_unix_socket(void); void seom(int sock); -void ssend(int sock, const char *format, ...); +void ssend(int sock, const char *format, ...) __attribute__ ((format (gnu_printf, 2, 3))); void swrite(int sock, void *value, size_t size); void *telnet_listening_thread_IPv4(void *args); void *telnet_listening_thread_IPv6(void *args); @@ -47,7 +47,7 @@ bool ipv6_available(void); void bind_sockets(void); void process_request(char *client_message, int *sock); -bool command(char *client_message, const char* cmd); +bool command(char *client_message, const char* cmd) __attribute__((pure)); bool matchesEndpoint(char *client_message, const char *cmd); // grep.c @@ -60,12 +60,12 @@ char * read_setupVarsconf(const char * key); void getSetupVarsArray(char * input); void clearSetupVarsArray(void); bool insetupVarsArray(char * str); -bool getSetupVarsBool(char * input); +bool getSetupVarsBool(char * input) __attribute__((pure)); void parse_args(int argc, char* argv[]); // setupVars.c -char* find_equals(const char* s); +char* find_equals(const char* s) __attribute__((pure)); void trim_whitespace(char *string); // config.c @@ -93,7 +93,7 @@ int db_query_int(const char*); // memory.c void memory_check(int which); 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 *FTLcalloc(size_t nmemb, size_t size, const char *file, const char *function, int line) __attribute__((malloc)); 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); @@ -112,7 +112,7 @@ void resolveForwardDestinations(bool onlynew); bool match_regex(char *input); void free_regex(void); void read_regex_from_file(void); -bool in_whitelist(char *domain); +bool in_whitelist(char *domain) __attribute__((pure)); // shmem.c bool init_shmem(void); diff --git a/setupVars.c b/setupVars.c index 7570aeb3..1cc9318c 100644 --- a/setupVars.c +++ b/setupVars.c @@ -30,7 +30,7 @@ void check_setupVarsconf(void) } } -char* find_equals(const char* s) +char* __attribute__((pure)) find_equals(const char* s) { const char* chars = "="; while (*s && (!chars || !strchr(chars, *s))) @@ -221,7 +221,7 @@ bool insetupVarsArray(char * str) return false; } -bool getSetupVarsBool(char * input) +bool __attribute__((pure)) getSetupVarsBool(char * input) { if((strcmp(input, "true")) == 0) return true; diff --git a/shmem.c b/shmem.c index 65494798..a0c8f118 100644 --- a/shmem.c +++ b/shmem.c @@ -457,7 +457,7 @@ void delete_shm(SharedMemory *sharedMemory) } // Euclidean algorithm to return greatest common divisor of the numbers -static size_t gcd(size_t a, size_t b) +static size_t __attribute__((const)) gcd(size_t a, size_t b) { while(b != 0) { diff --git a/signals.c b/signals.c index 9855c7a1..a0e39526 100644 --- a/signals.c +++ b/signals.c @@ -24,7 +24,7 @@ static void SIGSEGV_handler(int sig, siginfo_t *si, void *unused) if(FTLstarttime != 0) { - logg("FTL has been running for %i seconds", time(NULL)-FTLstarttime); + logg("FTL has been running for %li seconds", time(NULL)-FTLstarttime); } log_FTL_version(true); diff --git a/socket.c b/socket.c index a7354156..d181a919 100644 --- a/socket.c +++ b/socket.c @@ -209,7 +209,7 @@ void seom(int sock) pack_eom(sock); } -void ssend(int sock, const char *format, ...) +void __attribute__ ((format (gnu_printf, 2, 3))) ssend(int sock, const char *format, ...) { char *buffer; va_list args;