Change parse_string() to take an optional integer pointer that can
authorkrw <krw@openbsd.org>
Mon, 3 Apr 2017 19:59:39 +0000 (19:59 +0000)
committerkrw <krw@openbsd.org>
Mon, 3 Apr 2017 19:59:39 +0000 (19:59 +0000)
be used to return the final size of the parsed (i.e. un-vis'ed)
string. Use same, plus memcpy() to ensure entire final string is
copied to intended destination even if there are embedded NULs.

sbin/dhclient/clparse.c
sbin/dhclient/dhcpd.h
sbin/dhclient/parse.c

index 9660b10..7fbb674 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: clparse.c,v 1.107 2017/04/03 15:34:46 krw Exp $       */
+/*     $OpenBSD: clparse.c,v 1.108 2017/04/03 19:59:39 krw Exp $       */
 
 /* Parser for dhclient config and lease files. */
 
@@ -278,13 +278,13 @@ parse_client_statement(FILE *cfile, struct interface_info *ifi)
                parse_reject_statement(cfile);
                break;
        case TOK_FILENAME:
-               string = parse_string(cfile);
+               string = parse_string(cfile, NULL);
                free(config->filename);
                config->filename = string;
                parse_semi(cfile);
                break;
        case TOK_SERVER_NAME:
-               string = parse_string(cfile);
+               string = parse_string(cfile, NULL);
                free(config->server_name);
                config->server_name = string;
                parse_semi(cfile);
@@ -551,7 +551,7 @@ parse_client_lease_declaration(FILE *cfile, struct client_lease *lease,
     struct interface_info *ifi)
 {
        char *val;
-       int token;
+       int len, token;
 
        token = next_token(&val, cfile);
 
@@ -586,15 +586,17 @@ parse_client_lease_declaration(FILE *cfile, struct client_lease *lease,
                skip_to_semi(cfile);
                return;
        case TOK_FILENAME:
-               lease->filename = parse_string(cfile);
+               lease->filename = parse_string(cfile, NULL);
                break;
        case TOK_SERVER_NAME:
-               lease->server_name = parse_string(cfile);
+               lease->server_name = parse_string(cfile, NULL);
                break;
        case TOK_SSID:
-               val = parse_string(cfile);
-               if (val)
-                       strlcpy(lease->ssid, val, sizeof(lease->ssid));
+               val = parse_string(cfile, &len);
+               if (val && len <= sizeof(lease->ssid)) {
+                       memset(lease->ssid, 0, sizeof(lease->ssid));
+                       memcpy(lease->ssid, val, len);
+               }
                free(val);
                break;
        case TOK_RENEW:
@@ -668,10 +670,9 @@ parse_option_decl(FILE *cfile, struct option_data *options)
                                hunkix += len;
                                break;
                        case 't': /* Text string. */
-                               val = parse_string(cfile);
+                               val = parse_string(cfile, &len);
                                if (val == NULL)
                                        return (-1);
-                               len = strlen(val);
                                if (hunkix + len + 1 > sizeof(hunkbuf)) {
                                        parse_warn("option data buffer "
                                            "overflow");
index 907534d..ff24cc4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpd.h,v 1.161 2017/03/08 20:33:20 krw Exp $ */
+/*     $OpenBSD: dhcpd.h,v 1.162 2017/04/03 19:59:39 krw Exp $ */
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -203,7 +203,7 @@ int peek_token(char **, FILE *);
 extern int warnings_occurred;
 void skip_to_semi(FILE *);
 int parse_semi(FILE *);
-char *parse_string(FILE *);
+char *parse_string(FILE *, int *);
 int parse_ip_addr(FILE *, struct in_addr *);
 int parse_cidr(FILE *, unsigned char *);
 void parse_ethernet(FILE *, struct ether_addr *);
index 2ed7332..828ab6c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.c,v 1.47 2017/04/03 18:23:36 krw Exp $  */
+/*     $OpenBSD: parse.c,v 1.48 2017/04/03 19:59:39 krw Exp $  */
 
 /* Common parser code for dhcpd and dhclient. */
 
@@ -129,7 +129,7 @@ parse_semi(FILE *cfile)
 }
 
 char *
-parse_string(FILE *cfile)
+parse_string(FILE *cfile, int *len)
 {
        static char unvisbuf[1500];
        char *val, *s;
@@ -152,6 +152,8 @@ parse_string(FILE *cfile)
        if (!s)
                fatalx("no memory for string %s.", val);
        memcpy(s, unvisbuf, i+1);       /* copy terminating NUL */
+       if (len != NULL)
+               *len = i;
 
        return (s);
 }