]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
DHCP: Sanitise messages from servers for output
authorRoy Marples <roy@marples.name>
Sun, 21 Jun 2026 10:13:53 +0000 (11:13 +0100)
committerGitHub <noreply@github.com>
Sun, 21 Jun 2026 10:13:53 +0000 (11:13 +0100)
They could contain anything!

Reported by NVIDIA Project Vanessa

src/dhcp.c
src/dhcp6.c

index 799a74665ec6bbac0612007733778191a847cf78..915a6240503851072d1a112ab7627c5f24e49835 100644 (file)
@@ -495,7 +495,8 @@ static char *
 get_option_string(struct dhcpcd_ctx *ctx, const struct bootp *bootp,
     size_t bootp_len, uint8_t option)
 {
-       size_t len;
+       size_t len, sl;
+       ssize_t pl;
        const uint8_t *p;
        char *s;
 
@@ -503,10 +504,18 @@ get_option_string(struct dhcpcd_ctx *ctx, const struct bootp *bootp,
        if (!p || len == 0 || *p == '\0')
                return NULL;
 
-       s = malloc(sizeof(char) * (len + 1));
-       if (s) {
-               memcpy(s, p, len);
-               s[len] = '\0';
+       pl = print_string(NULL, 0, OT_ESCSTRING, p, len);
+       if (pl == -1)
+               return NULL;
+
+       sl = (size_t)pl + 1;
+       s = malloc(sl);
+       if (s != NULL) {
+               pl = print_string(s, sl, OT_ESCSTRING, p, len);
+               if (pl == -1) {
+                       free(s);
+                       return NULL;
+               }
        }
        return s;
 }
@@ -2949,25 +2958,9 @@ log_dhcp(int loglevel, const char *msg, const struct interface *ifp,
        int r;
        uint8_t overl;
 
-       if (strcmp(msg, "NAK:") == 0) {
+       if (strcmp(msg, "NAK:") == 0)
                a = get_option_string(ifp->ctx, bootp, bootp_len, DHO_MESSAGE);
-               if (a) {
-                       char *tmp;
-                       size_t al, tmpl;
-
-                       al = strlen(a);
-                       tmpl = (al * 4) + 1;
-                       tmp = malloc(tmpl);
-                       if (tmp == NULL) {
-                               logerr(__func__);
-                               free(a);
-                               return;
-                       }
-                       print_string(tmp, tmpl, OT_STRING, a, al);
-                       free(a);
-                       a = tmp;
-               }
-       } else if (ad && bootp->yiaddr != 0) {
+       else if (ad && bootp->yiaddr != 0) {
                addr.s_addr = bootp->yiaddr;
                a = strdup(inet_ntoa(addr));
                if (a == NULL) {
@@ -3222,12 +3215,7 @@ dhcp_handledhcp(struct interface *ifp, struct bootp *bootp, size_t bootp_len,
                }
 
                /* We should restart on a NAK */
-               LOGDHCP(LOG_WARNING, "NAK:");
-               if ((msg = get_option_string(ifp->ctx, bootp, bootp_len,
-                        DHO_MESSAGE))) {
-                       logwarnx("%s: message: %s", ifp->name, msg);
-                       free(msg);
-               }
+               LOGDHCP(LOG_WARNING, "NAK:");   /* This also logs DHO_MESSAGE */
                if (state->state == DHS_INFORM) /* INFORM should not be NAKed */
                        return;
                if (!(ifp->ctx->options & DHCPCD_TEST)) {
index 61a90633f36ec646899bf2c2911c4bb479bc8306..4a15319c01edc6b163b44a8fa9068cba96e6b9b1 100644 (file)
@@ -2129,6 +2129,7 @@ dhcp6_checkstatusok(const struct interface *ifp, struct dhcp6_message *m,
        opt += sizeof(code);
        mlen = opt_len - sizeof(code);
        if (mlen == 0) {
+       status_code:
                sbuf = NULL;
                if (code < sizeof(dhcp6_statuses) / sizeof(char *))
                        status = dhcp6_statuses[code];
@@ -2137,12 +2138,20 @@ dhcp6_checkstatusok(const struct interface *ifp, struct dhcp6_message *m,
                        status = buf;
                }
        } else {
-               if ((sbuf = malloc(mlen + 1)) == NULL) {
-                       logerr(__func__);
-                       return -1;
+               size_t slen;
+               ssize_t plen = print_string(NULL, 0, OT_ESCSTRING, opt, mlen);
+
+               if (plen == -1)
+                       goto status_code; /* log something */
+               slen = (size_t)plen + 1;
+               sbuf = malloc(slen);
+               if (sbuf == NULL)
+                       goto status_code; /* log something */
+
+               if (print_string(sbuf, slen, OT_ESCSTRING, opt, mlen) == -1) {
+                       free(sbuf);
+                       goto status_code;
                }
-               memcpy(sbuf, opt, mlen);
-               sbuf[mlen] = '\0';
                status = sbuf;
        }