Problems with automatic pkcs11 reinit on fork

Stef Walter stefw at
Mon Oct 10 18:10:32 CEST 2011

Thanks Alon, very helpful.

On 10/08/2011 07:16 PM, Alon Bar-Lev wrote:
> 1. I always assued that p11-kit was a transparent PKCS#11 provider
> that does extra functionality on behalf proxied providers. Maybe I am
> wrong.

Yes, that's one way to use p11-kit for applications that are not aware 
of p11-kit. However in the case of gnutls and other applications aware 
of p11-kit the applications are invoked directly.

However p11-kit does not aspire to be a wrapper library for PKCS#11. At 
least not yet ... there was some talk of merging pakchois into p11-kit, 
but it hasn't been p11-kit's core focus to try and abstract away PKCS#11.

> 3. If (1) is correct, and application is already using PKCS#11, it
> should follow the spec and do<something>  special when fork()ing, and
> nothing is needed.

Good point. Right, that makes sense. Handling forking correctly is an 
integral part of using PKCS#11. It may be that a wrapper library can 
hide this away, but it would be an extremely leaky abstraction.

> 4. Most provides miss this requirement, and even after
> re-initialization do not work properly. This is *THE* bug of providers
> when vendors port their provider into *POSIX, and won't be fixed
> anyway.

I see :/

> 5. Doing that transparent requires:
> a. Make sure application is designed properly to re-initialize any
> handle that is invalidate.
> b. Record pid of initialized process, and monitor all C_ functions for
> uninitialized process.
> c. Keep refcount for each C_ method, and wait for refcount=0 before
> fork(), this should be done at all process threads! (Most common,
> thread that polls for slot status).
> d. Free locks of all threads other than fork() thread before fork().
> e. Reinitialize after fork().

Right, that's a tough set of requirements. I might add that for 
requirement 'e', one cannot simply reinitialize inside a callback called 
from pthread_atfork() or similar. NSS and some other PKCS#11 modules use 
pthread_atfork() to watch for forks and set their internal state to 
uninitialized, so there's an inherent race condition here.



More information about the Gnutls-devel mailing list