diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c index d760c2cd0e..ae9fe00464 100644 --- a/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c +++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c @@ -49,6 +49,28 @@ enum _ThriftServerSocketProperties G_DEFINE_TYPE(ThriftServerSocket, thrift_server_socket, THRIFT_TYPE_SERVER_TRANSPORT) +static gboolean +thrift_server_socket_path_fits_unix_addr (const gchar *path, GError **error) +{ + const size_t path_len = strlen (path); + const size_t sun_path_len = sizeof (((struct sockaddr_un *) 0)->sun_path); + + if (path_len >= sun_path_len) + { + if (error != NULL) + { + g_set_error (error, + THRIFT_SERVER_SOCKET_ERROR, + THRIFT_SERVER_SOCKET_ERROR_BIND, + "unix socket path is too long (%zu bytes, max %zu)", + path_len, sun_path_len - 1); + } + return FALSE; + } + + return TRUE; +} + gboolean thrift_server_socket_listen (ThriftServerTransport *transport, GError **error) { @@ -80,6 +102,13 @@ thrift_server_socket_listen (ThriftServerTransport *transport, GError **error) /* bind to the socket */ if (tsocket->path) { + if (!thrift_server_socket_path_fits_unix_addr (tsocket->path, error)) + { + close (tsocket->sd); + tsocket->sd = THRIFT_INVALID_SOCKET; + return FALSE; + } + /* create a socket structure */ struct sockaddr_un pin; memset (&pin, 0, sizeof(pin)); diff --git a/lib/c_glib/test/testtransportsocket.c b/lib/c_glib/test/testtransportsocket.c index c23679716b..5f5dba55eb 100644 --- a/lib/c_glib/test/testtransportsocket.c +++ b/lib/c_glib/test/testtransportsocket.c @@ -323,6 +323,28 @@ test_open_rejects_too_long_unix_path (void) g_free (path); } +static void +test_server_listen_rejects_too_long_unix_path (void) +{ + ThriftServerSocket *tsocket = NULL; + ThriftServerTransport *transport = NULL; + GError *error = NULL; + gchar *path = make_too_long_unix_socket_path (); + + tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, + "path", path, + NULL); + transport = THRIFT_SERVER_TRANSPORT (tsocket); + + g_assert (thrift_server_transport_listen (transport, &error) == FALSE); + g_assert_error (error, THRIFT_SERVER_SOCKET_ERROR, THRIFT_SERVER_SOCKET_ERROR_BIND); + g_clear_error (&error); + g_assert (tsocket->sd == THRIFT_INVALID_SOCKET); + + g_object_unref (tsocket); + g_free (path); +} + static void thrift_socket_server_open (const int port, int times) { @@ -391,6 +413,7 @@ main(int argc, char *argv[]) g_test_add_func ("/testtransportsocket/ReadAndWrite", test_read_and_write); g_test_add_func ("/testtransportsocket/Peek", test_peek); g_test_add_func ("/testtransportsocket/OpenRejectsTooLongUnixPath", test_open_rejects_too_long_unix_path); + g_test_add_func ("/testtransportsocket/ServerListenRejectsTooLongUnixPath", test_server_listen_rejects_too_long_unix_path); return g_test_run (); }