]> granicus.if.org Git - p11-kit/commitdiff
In proxy module don't call C_Finalize on a forked process.
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 24 Jun 2015 07:43:57 +0000 (09:43 +0200)
committerStef Walter <stefw@redhat.com>
Mon, 29 Jun 2015 11:49:16 +0000 (13:49 +0200)
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

Reviewed-by: Stef Walter <stefw@redhat.com>
p11-kit/proxy.c

index db2acb811389f8381566a9da3b29773cc7556c1c..28fd18621ed0337247a15a812ac45d71bf835d00 100644 (file)
@@ -98,6 +98,7 @@ static State *all_instances = NULL;
 static State global = { { { { -1, -1 }, NULL, }, }, NULL, NULL, FIRST_HANDLE, NULL };
 
 #define PROXY_VALID(px) ((px) && (px)->forkid == p11_forkid)
+#define PROXY_FORKED(px) ((px) && (px)->forkid != p11_forkid)
 
 #define MANUFACTURER_ID         "PKCS#11 Kit                     "
 #define LIBRARY_DESCRIPTION     "PKCS#11 Kit Proxy Module        "
@@ -187,10 +188,11 @@ map_session_to_real (Proxy *px,
 }
 
 static void
-proxy_free (Proxy *py)
+proxy_free (Proxy *py, unsigned finalize)
 {
        if (py) {
-               p11_kit_modules_finalize (py->inited);
+               if (finalize)
+                       p11_kit_modules_finalize (py->inited);
                free (py->inited);
                p11_dict_free (py->sessions);
                free (py->mappings);
@@ -227,7 +229,7 @@ proxy_C_Finalize (CK_X_FUNCTION_LIST *self,
 
                p11_unlock ();
 
-               proxy_free (py);
+               proxy_free (py, 1);
        }
 
        p11_debug ("out: %lu", rv);
@@ -301,7 +303,7 @@ proxy_create (Proxy **res)
        }
 
        if (rv != CKR_OK) {
-               proxy_free (py);
+               proxy_free (py, 1);
                return rv;
        }
 
@@ -331,8 +333,13 @@ proxy_C_Initialize (CK_X_FUNCTION_LIST *self,
        p11_lock ();
 
                if (!PROXY_VALID (state->px)) {
+                       unsigned call_finalize = 1;
+
                        initialize = true;
-                       proxy_free (state->px);
+                       if (PROXY_FORKED(state->px))
+                               call_finalize = 0;
+                       proxy_free (state->px, call_finalize);
+
                        state->px = NULL;
                } else {
                        state->px->refs++;
@@ -360,7 +367,7 @@ proxy_C_Initialize (CK_X_FUNCTION_LIST *self,
 
        p11_unlock ();
 
-       proxy_free (py);
+       proxy_free (py, 1);
        p11_debug ("out: 0");
        return rv;
 }