Skip to content

Commit

Permalink
Reinit module only once after fork
Browse files Browse the repository at this point in the history
This prevent multiple threads from stomping on each other and reinit the
module multiple times.

Fixes #281

Signed-off-by: Simo Sorce <simo@redhat.com>
  • Loading branch information
simo5 committed Sep 7, 2023
1 parent cd2b377 commit dea8452
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct p11prov_module_ctx {

pthread_mutex_t lock;
bool initialized;
bool reinit;
};

/* This structure is effectively equivalent to CK_FUNCTION_LIST_3_0
Expand Down Expand Up @@ -364,6 +365,12 @@ void p11prov_module_free(P11PROV_MODULE *mctx)
OPENSSL_free(mctx);
}

/* should only be called by the fork handler */
void p11prov_module_mark_reinit(P11PROV_MODULE *mctx)
{
mctx->reinit = true;
}

CK_RV p11prov_module_reinit(P11PROV_MODULE *mctx)
{
CK_C_INITIALIZE_ARGS args = { 0 };
Expand All @@ -380,6 +387,11 @@ CK_RV p11prov_module_reinit(P11PROV_MODULE *mctx)
}

/* LOCKED SECTION ------------- */
if (!mctx->reinit) {
/* another thread already did it */
goto done;
}

P11PROV_debug("PKCS#11: Re-initializing the module: %s", mctx->path);

(void)p11prov_Finalize(mctx->provctx, NULL);
Expand All @@ -395,6 +407,9 @@ CK_RV p11prov_module_reinit(P11PROV_MODULE *mctx)
goto done;
}

/* clear reinit flag as we just did re-initialize */
mctx->reinit = false;

ret = p11prov_GetInfo(mctx->provctx, &ck_info);
if (ret != CKR_OK) {
goto done;
Expand Down
1 change: 1 addition & 0 deletions src/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ CK_RV p11prov_module_new(P11PROV_CTX *ctx, const char *path,
CK_RV p11prov_module_init(P11PROV_MODULE *mctx);
P11PROV_INTERFACE *p11prov_module_get_interface(P11PROV_MODULE *mctx);
void p11prov_module_free(P11PROV_MODULE *mctx);
void p11prov_module_mark_reinit(P11PROV_MODULE *mctx);
CK_RV p11prov_module_reinit(P11PROV_MODULE *mctx);
CK_RV p11prov_Initialize(P11PROV_CTX *ctx, CK_VOID_PTR pInitArgs);
CK_RV p11prov_Finalize(P11PROV_CTX *ctx, CK_VOID_PTR pReserved);
Expand Down
1 change: 1 addition & 0 deletions src/provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ static void fork_child(void)
if (ctx_pool.contexts[i]->status == P11PROV_INITIALIZED) {
/* can't re-init in the fork handler, mark it */
ctx_pool.contexts[i]->status = P11PROV_NEEDS_REINIT;
p11prov_module_mark_reinit(ctx_pool.contexts[i]->module);
p11prov_slot_fork_reset(ctx_pool.contexts[i]->slots);
}
}
Expand Down

0 comments on commit dea8452

Please sign in to comment.