Do not truncate socket path
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 1 Sep 2023 15:16:43 +0000 (18:16 +0300)
committerColin Clark <colin.clark@cclark.uk>
Sat, 2 Sep 2023 10:02:10 +0000 (11:02 +0100)
If the length of the socket path is too long to fit in the socket
structure, then we should fail, instead of possibly creating a socket
with an unexpected name, possibly in the the wrong directory.

Limit the socket path to one less than the maximum possible length, so
that the path is always followed by terminating '\0'. This matches
the recommendation in unix(7).

src/remote.cc

index 86c3fb4..5507223 100644 (file)
@@ -246,10 +246,15 @@ static RemoteConnection *remote_server_open(const gchar *path)
 {
        RemoteConnection *rc;
        struct sockaddr_un addr;
-       gint sun_path_len;
        gint fd;
        GIOChannel *channel;
 
+       if (strlen(path) >= sizeof(addr.sun_path))
+               {
+               log_printf("Address is too long: %s\n", path);
+               return nullptr;
+               }
+
        if (remote_server_exists(path))
                {
                log_printf("Address already in use: %s\n", path);
@@ -260,8 +265,7 @@ static RemoteConnection *remote_server_open(const gchar *path)
        if (fd == -1) return nullptr;
 
        addr.sun_family = AF_UNIX;
-       sun_path_len = MIN(strlen(path) + 1, UNIX_PATH_MAX);
-       strncpy(addr.sun_path, path, sun_path_len);
+       strncpy(addr.sun_path, path, sizeof(addr.sun_path));
        if (bind(fd, reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr)) == -1 ||
            listen(fd, REMOTE_SERVER_BACKLOG) == -1)
                {
@@ -300,17 +304,17 @@ static RemoteConnection *remote_client_open(const gchar *path)
        RemoteConnection *rc;
        struct stat st;
        struct sockaddr_un addr;
-       gint sun_path_len;
        gint fd;
 
+       if (strlen(path) >= sizeof(addr.sun_path)) return nullptr;
+
        if (stat(path, &st) != 0 || !S_ISSOCK(st.st_mode)) return nullptr;
 
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
        if (fd == -1) return nullptr;
 
        addr.sun_family = AF_UNIX;
-       sun_path_len = MIN(strlen(path) + 1, UNIX_PATH_MAX);
-       strncpy(addr.sun_path, path, sun_path_len);
+       strncpy(addr.sun_path, path, sizeof(addr.sun_path));
        if (connect(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) == -1)
                {
                DEBUG_1("error connecting to socket: %s", strerror(errno));