Bug 90289

Summary: C_Initialize deadlock after fork
Product: p11-glue Reporter: David Woodhouse <dwmw2>
Component: p11-kitAssignee: Stef Walter <stefw>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: medium CC: n.mavrogiannopoulos
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: simple test case

Description David Woodhouse 2015-05-02 21:27:52 UTC
Created attachment 115518 [details]
simple test case

The PKCS#11 Users Guide ยง2.5.2 at http://docs.oasis-open.org/pkcs11/pkcs11-ug/v2.40/cn02/pkcs11-ug-v2.40-cn02.html#_Toc406759987 advises that the child of a Cryptoki application, after forking, should call C_Initialize() to avoid leaving the module in an undefined state.

p11-kit-trust.so deadlocks when you do this:

#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x0000003841a0988d in __GI___pthread_mutex_lock (mutex=0x3860c64840 <p11_library_mutex>) at ../nptl/pthread_mutex_lock.c:80
#2  0x0000003860a1e812 in managed_C_Finalize (self=0x61ee00, reserved=<optimized out>) at p11-kit/modules.c:1546
#3  0x0000003860a396e0 in binding_C_Finalize (cif=<optimized out>, ret=0x7fffffffda60, args=<optimized out>, funcs=<optimized out>) at p11-kit/virtual.c:124
#4  0x0000003844205b9f in ffi_closure_unix64_inner (closure=0x7ffff7ff9048, rvalue=0x7fffffffda60, reg_args=0x7fffffffd9b0, argp=0x7fffffffda80 "PHb") at ../src/x86/ffi64.c:670
#5  0x0000003844205f18 in ffi_closure_unix64 () at ../src/x86/unix64.S:229
#6  0x0000003860a20ba1 in p11_kit_modules_finalize (modules=<optimized out>) at p11-kit/modules.c:2108
#7  0x0000003860a22132 in proxy_free (py=0x624810) at p11-kit/proxy.c:193
#8  0x0000003860a22303 in proxy_C_Initialize (self=0x623920, init_args=<optimized out>) at p11-kit/proxy.c:335
#9  0x0000003860a396c0 in binding_C_Initialize (cif=<optimized out>, ret=0x7fffffffdcc0, args=<optimized out>, funcs=<optimized out>) at p11-kit/virtual.c:114
#10 0x0000003844205b9f in ffi_closure_unix64_inner (closure=0x7ffff7ff96a0, rvalue=0x7fffffffdcc0, reg_args=0x7fffffffdc10, argp=0x7fffffffdce0 "`\t@") at ../src/x86/ffi64.c:670
#11 0x0000003844205f18 in ffi_closure_unix64 () at ../src/x86/unix64.S:229
#12 0x00000000004008e4 in main ()


It calls p11_lock() in proxy_C_Initialize() in frame 8 right before calling proxy_free(). And then when it calls it again in managed_C_Finalize() it deadlocks.

This is seen when attempting to use p11-kit-proxy.so from within OpenVPN (which is sad really, since I recently made OpenVPN do that by default if no other provider was specified...)
Comment 1 David Woodhouse 2015-05-02 22:29:30 UTC
I think it's wrong to be calling C_Finalize() on the loaded modules in the child anyway. The behaviour if you do that is undefined. If anything it needs to be calling C_Initialize(), surely?
Comment 2 Stef Walter 2015-06-29 11:50:35 UTC
Fixed by this patch in git master:

commit cacaf8cd0b0a4f2cd61b61b012cd5cbf715fe38f
Author: Nikos Mavrogiannopoulos <nmav@redhat.com>
Date:   Wed Jun 24 09:43:57 2015 +0200

    In proxy module don't call C_Finalize on a forked process.
    
    This corrects a deadlock on the forked process. The deadlock
    happened because the proxy called C_Finalize prior to a C_Initialize
    which is wrong according to PKCS #11 (2.40). This patch eliminates
    the C_Finalize call in that case.
    
    This resolves #90289
    https://bugs.freedesktop.org/show_bug.cgi?id=90289

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.