[PATCH] thunar-vcs-plugin: fix race condition in svn auth prompt

Stefan Sperling stsp at stsp.name
Wed Aug 22 13:31:38 CEST 2012


Fix a race condition in Subversion auth creds prompt functions.

Do not leave the critical section before destroying the login
prompt widget. Fixes hangs and crashes observed on OpenBSD during
updates from servers that require authentication. Most of the time
tvp-svn-helper would spin on the CPU after clicking 'OK' at the
password prompt and sometimes it would crash in various ways.

diff --git a/tvp-svn-helper/tsh-common.c b/tvp-svn-helper/tsh-common.c
index d7609a1..fa6cc15 100644
--- a/tvp-svn-helper/tsh-common.c
+++ b/tvp-svn-helper/tsh-common.c
@@ -322,18 +322,16 @@ tsh_auth_simple_prompt(svn_auth_cred_simple_t **cred,
 
 	if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
 	{
-		gdk_threads_leave();
-
 		*cred = NULL;
 
 		gtk_widget_destroy(dialog);
 
 		tsh_cancel();
+
+		gdk_threads_leave();
 		return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
 	}
 
-	gdk_threads_leave();
-
   ret = apr_pcalloc(pool, sizeof(svn_auth_cred_simple_t));
   login_dialog = TSH_LOGIN_DIALOG(dialog);
 	ret->username = apr_pstrdup(pool, tsh_login_dialog_get_username(login_dialog));
@@ -343,6 +341,7 @@ tsh_auth_simple_prompt(svn_auth_cred_simple_t **cred,
 
 	gtk_widget_destroy(dialog);
 
+	gdk_threads_leave();
 	return SVN_NO_ERROR;
 }
 
@@ -363,18 +362,16 @@ tsh_auth_username_prompt(svn_auth_cred_username_t **cred,
 
 	if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
 	{
-		gdk_threads_leave();
-
 		*cred = NULL;
 
 		gtk_widget_destroy(dialog);
 
 		tsh_cancel();
+
+		gdk_threads_leave();
 		return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
 	}
 
-	gdk_threads_leave();
-
   ret = apr_pcalloc(pool, sizeof(svn_auth_cred_username_t));
   login_dialog = TSH_LOGIN_DIALOG(dialog);
 	ret->username = apr_pstrdup(pool, tsh_login_dialog_get_username(login_dialog));
@@ -383,6 +380,7 @@ tsh_auth_username_prompt(svn_auth_cred_username_t **cred,
 
 	gtk_widget_destroy(dialog);
 
+	gdk_threads_leave();
 	return SVN_NO_ERROR;
 }
 
@@ -405,18 +403,16 @@ tsh_auth_ssl_server_trust_prompt(svn_auth_cred_ssl_server_trust_t **cred,
 
 	if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
 	{
-		gdk_threads_leave();
-
 		*cred = NULL;
 
 		gtk_widget_destroy(dialog);
 
 		tsh_cancel();
+
+		gdk_threads_leave();
 		return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
 	}
 
-	gdk_threads_leave();
-
   ret = apr_pcalloc(pool, sizeof(svn_auth_cred_ssl_server_trust_t));
   trust_dialog = TSH_TRUST_DIALOG(dialog);
 	ret->may_save = tsh_trust_dialog_get_may_save(trust_dialog);
@@ -425,6 +421,7 @@ tsh_auth_ssl_server_trust_prompt(svn_auth_cred_ssl_server_trust_t **cred,
 
 	gtk_widget_destroy(dialog);
 
+	gdk_threads_leave();
 	return SVN_NO_ERROR;
 }
 
@@ -445,18 +442,16 @@ tsh_auth_ssl_client_cert_prompt(svn_auth_cred_ssl_client_cert_t **cred,
 
 	if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
 	{
-		gdk_threads_leave();
-
 		*cred = NULL;
 
 		gtk_widget_destroy(dialog);
 
 		tsh_cancel();
+
+		gdk_threads_leave();
 		return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
 	}
 
-	gdk_threads_leave();
-
   ret = apr_pcalloc(pool, sizeof(svn_auth_cred_ssl_client_cert_t));
   file_dialog = TSH_FILE_DIALOG(dialog);
 	ret->cert_file = apr_pstrdup(pool, tsh_file_dialog_get_filename(file_dialog));
@@ -465,6 +460,7 @@ tsh_auth_ssl_client_cert_prompt(svn_auth_cred_ssl_client_cert_t **cred,
 
 	gtk_widget_destroy(dialog);
 
+	gdk_threads_leave();
 	return SVN_NO_ERROR;
 }
 
@@ -485,18 +481,16 @@ tsh_auth_ssl_client_cert_pw_prompt(svn_auth_cred_ssl_client_cert_pw_t **cred,
 
 	if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK)
 	{
-		gdk_threads_leave();
-
 		*cred = NULL;
 
 		gtk_widget_destroy(dialog);
 
 		tsh_cancel();
+
+		gdk_threads_leave();
 		return svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
 	}
 
-	gdk_threads_leave();
-
   ret = apr_pcalloc(pool, sizeof(svn_auth_cred_ssl_client_cert_pw_t));
   login_dialog = TSH_LOGIN_DIALOG(dialog);
 	ret->password = apr_pstrdup(pool, tsh_login_dialog_get_password(login_dialog));
@@ -505,6 +499,7 @@ tsh_auth_ssl_client_cert_pw_prompt(svn_auth_cred_ssl_client_cert_pw_t **cred,
 
 	gtk_widget_destroy(dialog);
 
+	gdk_threads_leave();
 	return SVN_NO_ERROR;
 }
 


More information about the Xfce4-dev mailing list