Use a separate (volatile) variable for certificate alias

If a connection is started while certificates are still loading and the
initiation is then canceled a deadlock could result if the daemon is
trying to enumerate the certificates just then.
This commit is contained in:
Tobias Brunner
2012-08-13 11:18:23 +02:00
parent a39a301a12
commit 9d0f8a3a95
@@ -46,6 +46,7 @@ public class CharonVpnService extends VpnService implements Runnable
private VpnProfileDataSource mDataSource; private VpnProfileDataSource mDataSource;
private Thread mConnectionHandler; private Thread mConnectionHandler;
private VpnProfile mCurrentProfile; private VpnProfile mCurrentProfile;
private volatile String mCurrentCertificateAlias;
private VpnProfile mNextProfile; private VpnProfile mNextProfile;
private volatile boolean mProfileUpdated; private volatile boolean mProfileUpdated;
private volatile boolean mTerminate; private volatile boolean mTerminate;
@@ -189,6 +190,10 @@ public class CharonVpnService extends VpnService implements Runnable
mCurrentProfile = mNextProfile; mCurrentProfile = mNextProfile;
mNextProfile = null; mNextProfile = null;
/* store this in a separate (volatile) variable to avoid
* a possible deadlock during deinitialization */
mCurrentCertificateAlias = mCurrentProfile.getCertificateAlias();
setProfile(mCurrentProfile); setProfile(mCurrentProfile);
setError(ErrorState.NO_ERROR); setError(ErrorState.NO_ERROR);
setState(State.CONNECTING); setState(State.CONNECTING);
@@ -350,7 +355,7 @@ public class CharonVpnService extends VpnService implements Runnable
* @param hash optional alias (only hash part), if given matching certificates are returned * @param hash optional alias (only hash part), if given matching certificates are returned
* @return a list of DER encoded CA certificates * @return a list of DER encoded CA certificates
*/ */
private synchronized byte[][] getTrustedCertificates(String hash) private byte[][] getTrustedCertificates(String hash)
{ {
ArrayList<byte[]> certs = new ArrayList<byte[]>(); ArrayList<byte[]> certs = new ArrayList<byte[]>();
TrustedCertificateManager certman = TrustedCertificateManager.getInstance(); TrustedCertificateManager certman = TrustedCertificateManager.getInstance();
@@ -373,7 +378,7 @@ public class CharonVpnService extends VpnService implements Runnable
} }
else else
{ {
String alias = this.mCurrentProfile.getCertificateAlias(); String alias = this.mCurrentCertificateAlias;
if (alias != null) if (alias != null)
{ {
X509Certificate cert = certman.getCACertificateFromAlias(alias); X509Certificate cert = certman.getCACertificateFromAlias(alias);