From daadae0bf58789fb3edf04cdefd3df4447873c7e Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Wed, 19 Mar 2014 19:32:45 -0400 Subject: [PATCH] Switch to using snprintf in dhcp.c and ifch.c so that truncations can be easily detected. --- ndhc/dhcp.c | 34 ++++++++++++++++++++-------------- ndhc/ifchd.c | 25 ++++++++++++++++++++----- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/ndhc/dhcp.c b/ndhc/dhcp.c index be1da05..6fee061 100644 --- a/ndhc/dhcp.c +++ b/ndhc/dhcp.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -52,7 +53,6 @@ #include "log.h" #include "io.h" #include "options.h" -#include "strl.h" #include "random.h" typedef enum { @@ -66,31 +66,37 @@ static int create_udp_socket(uint32_t ip, uint16_t port, char *iface) { int fd; if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - log_error("create_udp_socket: socket failed: %s", strerror(errno)); + log_error("%s: (%s) socket failed: %s", + client_config.interface, __func__, strerror(errno)); goto out; } int opt = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof opt) == -1) { - log_error("create_udp_socket: Set reuse addr failed: %s", - strerror(errno)); + log_error("%s: (%s) Set reuse addr failed: %s", + client_config.interface, __func__, strerror(errno)); goto out_fd; } if (setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &opt, sizeof opt) == -1) { - log_error("create_udp_socket: Set don't route failed: %s", - strerror(errno)); + log_error("%s: (%s) Set don't route failed: %s", + client_config.interface, __func__, strerror(errno)); goto out_fd; } struct ifreq ifr; - memset(&ifr, 0, sizeof (struct ifreq)); - strnkcpy(ifr.ifr_name, iface, IFNAMSIZ); + memset(&ifr, 0, sizeof ifr); + ssize_t sl = snprintf(ifr.ifr_name, sizeof ifr.ifr_name, "%s", iface); + if (sl < 0 || (size_t)sl >= sizeof ifr.ifr_name) { + log_error("%s: (%s) Set interface name failed.", + client_config.interface, __func__); + goto out_fd; + } if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof ifr) < 0) { - log_error("create_udp_socket: Set bind to device failed: %s", - strerror(errno)); + log_error("%s: (%s) Set bind to device failed: %s", + client_config.interface, __func__, strerror(errno)); goto out_fd; } if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) == -1) { - log_error("create_udp_socket: Set non-blocking failed: %s", - strerror(errno)); + log_error("%s: (%s) Set non-blocking failed: %s", + client_config.interface, __func__, strerror(errno)); goto out_fd; } @@ -118,8 +124,8 @@ static int create_udp_listen_socket(char *inf) return -1; int opt = 1; if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &opt, sizeof opt) == -1) { - log_error("create_udp_listen_socket: Set broadcast failed: %s", - strerror(errno)); + log_error("%s: (%s) Set broadcast failed: %s", + client_config.interface, __func__, strerror(errno)); close(fd); return -1; } diff --git a/ndhc/ifchd.c b/ndhc/ifchd.c index b49f986..ac1b7f6 100644 --- a/ndhc/ifchd.c +++ b/ndhc/ifchd.c @@ -52,7 +52,6 @@ #include "pidfile.h" #include "signals.h" #include "ifchd-parse.h" -#include "strl.h" #include "cap.h" #include "io.h" #include "sys.h" @@ -106,7 +105,11 @@ static void write_resolve_conf(void) q = strchr(p, '\0'); else *q++ = '\0'; - strnkcpy(buf, p, sizeof buf); + ssize_t sl = snprintf(buf, sizeof buf, "%s", p); + if (sl < 0 || (size_t)sl >= sizeof buf) { + log_warning("%s: (%s) snprintf failed appending nameservers", + client_config.interface, __func__); + } writeordie(resolv_conf_fd, ns_str, strlen(ns_str)); writeordie(resolv_conf_fd, buf, strlen(buf)); @@ -123,7 +126,11 @@ static void write_resolve_conf(void) q = strchr(p, '\0'); else *q++ = '\0'; - strnkcpy(buf, p, sizeof buf); + ssize_t sl = snprintf(buf, sizeof buf, "%s", p); + if (sl < 0 || (size_t)sl >= sizeof buf) { + log_warning("%s: (%s) snprintf failed appending domains", + client_config.interface, __func__); + } if (numdoms == 0) { writeordie(resolv_conf_fd, dom_str, strlen(dom_str)); @@ -185,7 +192,11 @@ void perform_dns(const char *str, size_t len) log_line("DNS server list is too long: %zu > %zu", len, cl.namesvrs); return; } - strnkcpy(cl.namesvrs, str, sizeof cl.namesvrs); + ssize_t sl = snprintf(cl.namesvrs, sizeof cl.namesvrs, "%s", str); + if (sl < 0 || (size_t)sl >= sizeof cl.namesvrs) { + log_warning("%s: (%s) snprintf failed", + client_config.interface, __func__); + } write_resolve_conf(); log_line("Added DNS server: '%s'", str); } @@ -217,7 +228,11 @@ void perform_domain(const char *str, size_t len) log_line("DNS domain list is too long: %zu > %zu", len, cl.namesvrs); return; } - strnkcpy(cl.domains, str, sizeof cl.domains); + ssize_t sl = snprintf(cl.domains, sizeof cl.domains, "%s", str); + if (sl < 0 || (size_t)sl >= sizeof cl.domains) { + log_warning("%s: (%s) snprintf failed", + client_config.interface, __func__); + } write_resolve_conf(); log_line("Added DNS domain: '%s'", str); }