Skip to content

Commit

Permalink
GUACAMOLE-1732: Prevent deadlock and enhance cleanup in RDP client.
Browse files Browse the repository at this point in the history
  • Loading branch information
aleitner committed Mar 9, 2024
1 parent e724d03 commit 2cd233c
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/protocols/rdp/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "common-ssh/user.h"
#endif

#include <guacamole/argv.h>
#include <guacamole/audio.h>
#include <guacamole/client.h>
#include <guacamole/mem.h>
Expand Down Expand Up @@ -241,6 +242,14 @@ int guac_rdp_client_free_handler(guac_client* client) {

guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;

/*
* Signals any threads that are blocked awaiting user input for authentication
* (e.g., username or password) to terminate their wait. By broadcasting a
* condition signal, the authentication process is interrupted, allowing for
* premature termination and cleanup during client disconnection.
*/
guac_argv_stop();

/* Wait for client thread */
pthread_join(rdp_client->client_thread, NULL);

Expand Down Expand Up @@ -306,4 +315,3 @@ int guac_rdp_client_free_handler(guac_client* client) {
return 0;

}

12 changes: 12 additions & 0 deletions src/protocols/rdp/rdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,12 +525,24 @@ static int guac_rdp_handle_connection(guac_client* client) {
/* Set default pointer */
guac_common_cursor_set_pointer(rdp_client->display->cursor);

/*
* Downgrade the lock to allow for concurrent read access
* Access to read locks need to be made available for other processes to use
* while we await credentials from the user.
*/
pthread_rwlock_unlock(&(rdp_client->lock));
pthread_rwlock_rdlock(&(rdp_client->lock));

/* Connect to RDP server */
if (!freerdp_connect(rdp_inst)) {
guac_rdp_client_abort(client, rdp_inst);
goto fail;
}

/* Upgrade to write lock again for further exclusive operations */
pthread_rwlock_unlock(&(rdp_client->lock));
pthread_rwlock_wrlock(&(rdp_client->lock));

/* Connection complete */
rdp_client->rdp_inst = rdp_inst;

Expand Down

0 comments on commit 2cd233c

Please sign in to comment.