[gnome-remote-desktop] rdp-server: Cleanup resources directly when stopping the server



commit 9b3b4ec068bd0160ca7b0cae208eb39d52b2b349
Author: Pascal Nowack <Pascal Nowack gmx de>
Date:   Sat Feb 26 12:23:06 2022 +0100

    rdp-server: Cleanup resources directly when stopping the server
    
    To stop the RDP server, gnome-remote-desktop currently calls
    grd_rdp_server_stop() to stop the socket listener and then unrefs the
    server instance, where also all current RDP sessions are supposed to be
    cleaned up.
    This works fine, when just the backend is disabled, but
    gnome-remote-desktop continues to run.
    However, when the daemon is shut down, this is not the case:
    Although the server backends are cleaned up before the GrdContext
    instance, the context instance is in reality cleaned up first.
    This is visible in the form that glib does not run the dispose()
    function in the server class directly.
    The reason for this is that the GSource for the socket callback also
    has its internal reference.
    This GSource cleans up its reference, when the G_IO_NVAL value is
    returned from its fd.
    
    The effect of the current handling is that gnome-remote-desktop
    crashes, when the daemon exits.
    To prevent this crash, clean up the internal server resources in
    grd_rdp_server_stop() too.
    This ensures that the destruction order is kept and no use-after-free
    situations happen, when the daemon exits.

 src/grd-rdp-server.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)
---
diff --git a/src/grd-rdp-server.c b/src/grd-rdp-server.c
index 41963f9b..9f8b3efa 100644
--- a/src/grd-rdp-server.c
+++ b/src/grd-rdp-server.c
@@ -176,6 +176,20 @@ grd_rdp_server_stop (GrdRdpServer *rdp_server)
 {
   g_socket_service_stop (G_SOCKET_SERVICE (rdp_server));
   g_socket_listener_close (G_SOCKET_LISTENER (rdp_server));
+
+  while (rdp_server->sessions)
+    {
+      GrdSession *session = rdp_server->sessions->data;
+
+      grd_session_stop (session);
+    }
+
+  g_clear_handle_id (&rdp_server->cleanup_sessions_idle_id, g_source_remove);
+  grd_rdp_server_cleanup_stopped_sessions (rdp_server);
+
+#ifdef HAVE_HWACCEL_NVIDIA
+  g_clear_object (&rdp_server->hwaccel_nvidia);
+#endif /* HAVE_HWACCEL_NVIDIA */
 }
 
 static void
@@ -220,18 +234,12 @@ grd_rdp_server_dispose (GObject *object)
 {
   GrdRdpServer *rdp_server = GRD_RDP_SERVER (object);
 
-  while (rdp_server->sessions)
-    {
-      GrdSession *session = rdp_server->sessions->data;
-
-      grd_session_stop (session);
-    }
-
-  g_clear_handle_id (&rdp_server->cleanup_sessions_idle_id, g_source_remove);
-  grd_rdp_server_cleanup_stopped_sessions (rdp_server);
+  g_assert (!rdp_server->sessions);
+  g_assert (!rdp_server->cleanup_sessions_idle_id);
+  g_assert (!rdp_server->stopped_sessions);
 
 #ifdef HAVE_HWACCEL_NVIDIA
-  g_clear_object (&rdp_server->hwaccel_nvidia);
+  g_assert (!rdp_server->hwaccel_nvidia);
 #endif /* HAVE_HWACCEL_NVIDIA */
 
   G_OBJECT_CLASS (grd_rdp_server_parent_class)->dispose (object);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]