diff --git a/src/dns.c b/src/dns.c index 7746d216c0..5a4fc2747a 100644 --- a/src/dns.c +++ b/src/dns.c @@ -22,6 +22,7 @@ #include "tlog.h" #include #include +#include #include #include #include @@ -52,9 +53,14 @@ static unsigned short _dns_read_short(unsigned char **buffer) { unsigned short value = 0; - value = ntohs(*((unsigned short *)(*buffer))); + if ((uintptr_t)(*buffer) % 2 == 0) { + value = *((unsigned short *)(*buffer)); + } else { + memcpy(&value, *buffer, 2); + } + *buffer += 2; - return value; + return ntohs(value); } /* write char and move pointer */ @@ -76,7 +82,35 @@ static unsigned char _dns_read_char(unsigned char **buffer) static void _dns_write_short(unsigned char **buffer, unsigned short value) { value = htons(value); - *((unsigned short *)(*buffer)) = value; + + if ((uintptr_t)(*buffer) % 2 == 0) { + *((unsigned short *)(*buffer)) = value; + } else { + memcpy(*buffer, &value, 2); + } + + *buffer += 2; +} + +/* write short and move pointer */ +static void _dns_write_shortptr(unsigned char **buffer, void *ptrvalue) +{ + unsigned short value; + + if ((uintptr_t)ptrvalue % 2 == 0) { + value = *(unsigned short *)ptrvalue; + } else { + memcpy(&value, ptrvalue, 2); + } + + value = htons(value); + + if ((uintptr_t)(*buffer) % 2 == 0) { + *((unsigned short *)(*buffer)) = value; + } else { + memcpy(*buffer, &value, 2); + } + *buffer += 2; } @@ -84,7 +118,31 @@ static void _dns_write_short(unsigned char **buffer, unsigned short value) static void _dns_write_int(unsigned char **buffer, unsigned int value) { value = htonl(value); - *((unsigned int *)(*buffer)) = value; + if ((uintptr_t)(*buffer) % 4 == 0) { + *((unsigned int *)(*buffer)) = value; + } else { + memcpy(*buffer, &value, 4); + } + *buffer += 4; +} + +/* write int and move pointer */ +static void _dns_write_intptr(unsigned char **buffer, void *ptrvalue) +{ + unsigned int value; + + if ((uintptr_t)ptrvalue % 4 == 0) { + value = *(unsigned int *)ptrvalue; + } else { + memcpy(&value, ptrvalue, 4); + } + + value = htonl(value); + if ((uintptr_t)(*buffer) % 4 == 0) { + *((unsigned int *)(*buffer)) = value; + } else { + memcpy(*buffer, &value, 4); + } *buffer += 4; } @@ -93,10 +151,14 @@ static unsigned int _dns_read_int(unsigned char **buffer) { unsigned int value = 0; - value = ntohl(*((unsigned int *)(*buffer))); - *buffer += 4; + if ((uintptr_t)(*buffer) % 4 == 0) { + value = *((unsigned int *)(*buffer)); + } else { + memcpy(&value, *buffer, 4); + } - return value; + *buffer += 4; + return ntohl(value); } static inline int _dns_left_len(struct dns_context *context) @@ -1782,15 +1844,15 @@ static int _dns_encode_SOA(struct dns_context *context, struct dns_rrs *rrs) return -1; } - _dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr); + _dns_write_intptr(&context->ptr, data_context.ptr); data_context.ptr += 4; - _dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr); + _dns_write_intptr(&context->ptr, data_context.ptr); data_context.ptr += 4; - _dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr); + _dns_write_intptr(&context->ptr, data_context.ptr); data_context.ptr += 4; - _dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr); + _dns_write_intptr(&context->ptr, data_context.ptr); data_context.ptr += 4; - _dns_write_int(&context->ptr, *(unsigned int *)data_context.ptr); + _dns_write_intptr(&context->ptr, data_context.ptr); data_context.ptr += 4; return 0; @@ -1824,11 +1886,11 @@ static int _dns_encode_SRV(struct dns_context *context, struct dns_rrs *rrs) return -1; } - _dns_write_short(&context->ptr, *(unsigned short *)data_context.ptr); + _dns_write_shortptr(&context->ptr, data_context.ptr); data_context.ptr += 2; - _dns_write_short(&context->ptr, *(unsigned short *)data_context.ptr); + _dns_write_shortptr(&context->ptr, data_context.ptr); data_context.ptr += 2; - _dns_write_short(&context->ptr, *(unsigned short *)data_context.ptr); + _dns_write_shortptr(&context->ptr, data_context.ptr); data_context.ptr += 2; rr_len += 6; diff --git a/src/dns.h b/src/dns.h index 82868cfa46..589497d0e2 100644 --- a/src/dns.h +++ b/src/dns.h @@ -149,12 +149,12 @@ struct dns_head { struct dns_packet_dict_item { unsigned short pos; unsigned int hash; -}; +} __attribute__((packed)); struct dns_packet_dict { short dict_count; struct dns_packet_dict_item names[DNS_PACKET_DICT_SIZE]; -}; +} __attribute__((packed)); /* packet head */ struct dns_packet { @@ -179,7 +179,7 @@ struct dns_rrs { unsigned short len; int type; unsigned char data[0]; -}; +} __attribute__((packed)); /* packet encode/decode context */ struct dns_context { diff --git a/src/dns_server.c b/src/dns_server.c index 774dd52822..92fa3b3a73 100644 --- a/src/dns_server.c +++ b/src/dns_server.c @@ -277,12 +277,12 @@ struct dns_request { unsigned short ss_family; char remote_server_fail; char skip_qtype_soa; - socklen_t addr_len; union { struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr addr; }; + socklen_t addr_len; struct sockaddr_storage localaddr; int has_ecs; struct dns_opt_ecs ecs; diff --git a/src/tlog.c b/src/tlog.c index e61ff026ee..a3df47d7ad 100644 --- a/src/tlog.c +++ b/src/tlog.c @@ -37,7 +37,7 @@ #define TLOG_TMP_LEN 128 #define TLOG_LOG_SIZE (1024 * 1024 * 50) #define TLOG_LOG_COUNT 32 -#define TLOG_LOG_NAME_LEN 128 +#define TLOG_LOG_NAME_LEN 256 #define TLOG_BUFF_LEN (PATH_MAX + TLOG_LOG_NAME_LEN * 3) #define TLOG_SUFFIX_GZ ".gz" #define TLOG_SUFFIX_LOG "" @@ -892,7 +892,7 @@ static int _tlog_get_oldest_callback(const char *path, struct dirent *entry, voi if (oldestlog->mtime == 0 || oldestlog->mtime > sb.st_mtime) { oldestlog->mtime = sb.st_mtime; - strncpy(oldestlog->name, entry->d_name, sizeof(oldestlog->name) - 1); + strncpy(oldestlog->name, entry->d_name, sizeof(oldestlog->name)); oldestlog->name[sizeof(oldestlog->name) - 1] = '\0'; return 0; } @@ -1207,11 +1207,11 @@ static void _tlog_get_log_name_dir(struct tlog_log *log) pthread_mutex_lock(&tlog.lock); strncpy(log_file, log->pending_logfile, sizeof(log_file) - 1); log_file[sizeof(log_file) - 1] = '\0'; - strncpy(log->logdir, dirname(log_file), sizeof(log->logdir)); + strncpy(log->logdir, dirname(log_file), sizeof(log->logdir) - 1); log->logdir[sizeof(log->logdir) - 1] = '\0'; strncpy(log_file, log->pending_logfile, PATH_MAX); log_file[sizeof(log_file) - 1] = '\0'; - strncpy(log->logname, basename(log_file), sizeof(log->logname)); + strncpy(log->logname, basename(log_file), sizeof(log->logname) - 1); log->logname[sizeof(log->logname) - 1] = '\0'; pthread_mutex_unlock(&tlog.lock); } diff --git a/src/util.c b/src/util.c index 2b57274a60..f9370f31aa 100644 --- a/src/util.c +++ b/src/util.c @@ -844,10 +844,10 @@ int netlink_get_neighbors(int family, continue; } - for (nlh = (struct nlmsghdr *)buf; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) { + unsigned int rtalen = len; + for (nlh = (struct nlmsghdr *)buf; NLMSG_OK(nlh, rtalen); nlh = NLMSG_NEXT(nlh, rtalen)) { ndm = NLMSG_DATA(nlh); struct rtattr *rta = RTM_RTA(ndm); - int rtalen = RTM_PAYLOAD(nlh); const uint8_t *mac = NULL; const uint8_t *net_addr = NULL; int net_addr_len = 0;