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 74def297176..d760c2cd0e8 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 @@ -374,4 +374,3 @@ thrift_server_socket_class_init (ThriftServerSocketClass *cls) tstc->accept = thrift_server_socket_accept; tstc->close = thrift_server_socket_close; } - diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c index 8d3d09e893c..ff05723caf0 100644 --- a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c +++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.c @@ -45,6 +45,28 @@ enum _ThriftSocketProperties G_DEFINE_TYPE(ThriftSocket, thrift_socket, THRIFT_TYPE_TRANSPORT) +static gboolean +thrift_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_TRANSPORT_ERROR, + THRIFT_TRANSPORT_ERROR_SOCKET, + "unix socket path is too long (%zu bytes, max %zu)", + path_len, sun_path_len - 1); + } + return FALSE; + } + + return TRUE; +} + /* implements thrift_transport_is_open */ gboolean thrift_socket_is_open (ThriftTransport *transport) @@ -135,8 +157,13 @@ thrift_socket_open (ThriftTransport *transport, GError **error) ThriftSocket *tsocket = THRIFT_SOCKET (transport); g_return_val_if_fail (tsocket->sd == THRIFT_INVALID_SOCKET, FALSE); - + if (tsocket->path) { + if (!thrift_socket_path_fits_unix_addr (tsocket->path, error)) + { + 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 89c61b91019..c23679716ba 100644 --- a/lib/c_glib/test/testtransportsocket.c +++ b/lib/c_glib/test/testtransportsocket.c @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -71,6 +72,18 @@ my_send(int socket, const void *buffer, size_t length, int flags) static void thrift_socket_server (const int port); static void thrift_socket_server_open (const int port, int times); + +static gchar * +make_too_long_unix_socket_path (void) +{ + struct sockaddr_un addr; + const size_t path_len = sizeof (addr.sun_path) + 1; + gchar *path = g_malloc (path_len + 1); + + memset (path, 'a', path_len); + path[path_len] = '\0'; + return path; +} /* test object creation and destruction */ static void test_create_and_destroy(void) @@ -288,6 +301,28 @@ test_peek(void) } } +static void +test_open_rejects_too_long_unix_path (void) +{ + ThriftSocket *tsocket = NULL; + ThriftTransport *transport = NULL; + GError *error = NULL; + gchar *path = make_too_long_unix_socket_path (); + + tsocket = g_object_new (THRIFT_TYPE_SOCKET, + "path", path, + NULL); + transport = THRIFT_TRANSPORT (tsocket); + + g_assert (thrift_socket_open (transport, &error) == FALSE); + g_assert_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SOCKET); + g_clear_error (&error); + g_assert (thrift_socket_is_open (transport) == FALSE); + + g_object_unref (tsocket); + g_free (path); +} + static void thrift_socket_server_open (const int port, int times) { @@ -355,7 +390,7 @@ main(int argc, char *argv[]) g_test_add_func ("/testtransportsocket/OpenAndClose", test_open_and_close); 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); return g_test_run (); } -