Switch to using snprintf in dhcp.c and ifch.c so that truncations can be
easily detected.
This commit is contained in:
		
							
								
								
									
										34
									
								
								ndhc/dhcp.c
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								ndhc/dhcp.c
									
									
									
									
									
								
							@@ -28,6 +28,7 @@
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								ndhc/ifchd.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user