[gnutls-dev] thread safety issue in
gnutls_certificate_verify_peers2()
Rupert Kittinger
rkit at mur.at
Thu Mar 9 22:05:53 CET 2006
Hi everybody,
I have found an unexpected race condition in using gnutls in an
multithreaded application.
It is a multithreaded tcp server, where each thread handles its own
session. It uses x509 certificates and requires client certification.
All threads share the same certificate_credentials structure. I would
have expected that the credentials structure is read-only and does not
need explicit locking, but unfortunately...
Under heavy load, the server crashes reproducably in
gnutls_certificate_verify_peers2(). After some debugging, I found the
following:
asn1_der_coding() seems to modify its first argument (ASN1_TYPE element)
when encoding seuences or sets. e.g.
case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
if(move!=UP){
_asn1_ltostr(counter,temp);
tlen = strlen(temp);
if (tlen > 0)
_asn1_set_value(p,temp,tlen+1);
p=p->down;
...
where p seems to point inside the asn1 structure. The program crashes
when _asn1_set_value() frees the node while another thread is reading
the same structure and tries to dereference a null pointer.
What is the reason for writing inside the structure? I admit I did not
tr yto understand the der encoding code in detail, it looks quite
intimidating :-)
Protecting the call to gnutls_certificate_verify_peers2() is an
acceptable workaround, but I would suggest fixing this issue inside
libtasn1. At the very least, there should be a hint inside the
documentation that credentials should not be shared between threads.
The window of opportunity for this race condition is very short, and I
have not yet been able to reproduce it on a single-cpu machine :-(
cheers,
Rupert
PS: thanks for all your efforts!
--
Rupert Kittinger <rkit at mur.at>
Krenngasse 32
A-8010 Graz
Austria
More information about the Gnutls-dev
mailing list