Blob Blame History Raw
From 79244173353d95149ad1944f61cc6bd2e43bd7d4 Mon Sep 17 00:00:00 2001
From: ellie timoney <ellie@fastmail.com>
Date: Tue, 20 Feb 2018 13:17:39 +1100
Subject: [PATCH] master: reject unix domain listen paths that are too long

Fixes #2253
---
 master/master.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/master/master.c b/master/master.c
index 325afd42f..a28731fd0 100644
--- a/master/master.c
+++ b/master/master.c
@@ -496,6 +496,12 @@ static void service_create(struct service *s)
                 EX_SOFTWARE);
 
     if (s->listen[0] == '/') { /* unix socket */
+        if (strlen(s->listen) >= sizeof(sunsock.sun_path)) {
+            syslog(LOG_ERR, "invalid listen '%s' (too long), disabling %s",
+                   s->listen, s->name);
+            service_forget_exec(s);
+            return;
+        }
         res0_is_local = 1;
         res0 = (struct addrinfo *)xzmalloc(sizeof(struct addrinfo));
         res0->ai_flags = AI_PASSIVE;
@@ -513,7 +519,14 @@ static void service_create(struct service *s)
         sunsock.sun_len = res0->ai_addrlen;
 #endif
         sunsock.sun_family = AF_UNIX;
-        strcpy(sunsock.sun_path, s->listen);
+
+        int r = snprintf(sunsock.sun_path, sizeof(sunsock.sun_path), "%s", s->listen);
+        if (r < 0 || (size_t) r >= sizeof(sunsock.sun_path)) {
+            /* belt and suspenders */
+            fatal("Serious software bug found: "
+                  "over-long listen path not detected earlier!",
+                  EX_SOFTWARE);
+        }
         unlink(s->listen);
     } else { /* inet socket */
         char *port;