]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: unix: better catch situations where the unix socket path length is close...
authorWilly Tarreau <w@1wt.eu>
Tue, 11 Feb 2020 05:43:37 +0000 (06:43 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 11 Feb 2020 05:49:42 +0000 (06:49 +0100)
We do have some checks for the UNIX socket path length to validate the
full pathname of a unix socket but the pathname extension is only taken
into account when using a bind_prefix. The second check only matches
against MAXPATHLEN. So this means that path names between 98 and 108
might successfully parse but fail to bind. Let's adjust the check in
the address parser and refine the error checking at the bind() step.

This addresses bug #493.

src/proto_uxst.c
src/standard.c

index 4c32f7eb07038f1baa23cf182704e1b7f200b643..2a5e4319da81ce783539473652da35cd7db07831 100644 (file)
@@ -187,6 +187,7 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
        struct sockaddr_un addr;
        const char *msg = NULL;
        const char *path;
+       int maxpathlen;
        int ext, ready;
        socklen_t ready_len;
        int err;
@@ -205,6 +206,8 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
                listener->fd = uxst_find_compatible_fd(listener);
        path = ((struct sockaddr_un *)&listener->addr)->sun_path;
 
+       maxpathlen = MIN(MAXPATHLEN, sizeof(addr.sun_path));
+
        /* if the listener already has an fd assigned, then we were offered the
         * fd by an external process (most likely the parent), and we don't want
         * to create a new socket. However we still want to set a few flags on
@@ -216,17 +219,17 @@ static int uxst_bind_listener(struct listener *listener, char *errmsg, int errle
                goto fd_ready;
 
        if (path[0]) {
-               ret = snprintf(tempname, MAXPATHLEN, "%s.%d.tmp", path, pid);
-               if (ret < 0 || ret >= MAXPATHLEN) {
+               ret = snprintf(tempname, maxpathlen, "%s.%d.tmp", path, pid);
+               if (ret < 0 || ret >= maxpathlen) {
                        err |= ERR_FATAL | ERR_ALERT;
-                       msg = "name too long for UNIX socket";
+                       msg = "name too long for UNIX socket (limit usually 97)";
                        goto err_return;
                }
 
-               ret = snprintf(backname, MAXPATHLEN, "%s.%d.bak", path, pid);
-               if (ret < 0 || ret >= MAXPATHLEN) {
+               ret = snprintf(backname, maxpathlen, "%s.%d.bak", path, pid);
+               if (ret < 0 || ret >= maxpathlen) {
                        err |= ERR_FATAL | ERR_ALERT;
-                       msg = "name too long for UNIX socket";
+                       msg = "name too long for UNIX socket (limit usually 97)";
                        goto err_return;
                }
 
index 442348c4ae37792110136e82aa8a2ef554bedcf9..3c4081ebb6df1a78a46787db2083c84501b1a336 100644 (file)
@@ -938,7 +938,7 @@ struct sockaddr_storage *str2sa_range(const char *str, int *port, int *low, int
                 */
                prefix_path_len = (pfx && !abstract) ? strlen(pfx) : 0;
                max_path_len = (sizeof(un->sun_path) - 1) -
-                       (prefix_path_len ? prefix_path_len + 1 + 5 + 1 + 3 : 0);
+                       (abstract ? 0 : prefix_path_len + 1 + 5 + 1 + 3);
 
                adr_len = strlen(str2);
                if (adr_len > max_path_len) {