Address issue with C_Initialize after fork()
Resolves: rhbz#1218797
This commit is contained in:
parent
798fb5ed71
commit
c7c9618926
228
opensc-0.15.0-fork-issue.patch
Normal file
228
opensc-0.15.0-fork-issue.patch
Normal file
@ -0,0 +1,228 @@
|
||||
diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c
|
||||
index 4670008..26f8bf5 100644
|
||||
--- a/src/libopensc/ctx.c
|
||||
+++ b/src/libopensc/ctx.c
|
||||
@@ -791,19 +791,21 @@ int sc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **
|
||||
}
|
||||
|
||||
|
||||
-int sc_release_context(sc_context_t *ctx)
|
||||
+static
|
||||
+int __sc_release_context(sc_context_t *ctx, unsigned after_fork)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
assert(ctx != NULL);
|
||||
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
|
||||
+
|
||||
while (list_size(&ctx->readers)) {
|
||||
sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0);
|
||||
_sc_delete_reader(ctx, rdr);
|
||||
}
|
||||
|
||||
if (ctx->reader_driver->ops->finish != NULL)
|
||||
- ctx->reader_driver->ops->finish(ctx);
|
||||
+ ctx->reader_driver->ops->finish(ctx, after_fork);
|
||||
|
||||
for (i = 0; ctx->card_drivers[i]; i++) {
|
||||
struct sc_card_driver *drv = ctx->card_drivers[i];
|
||||
@@ -836,6 +838,16 @@ int sc_release_context(sc_context_t *ctx)
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
+int sc_release_context(sc_context_t *ctx)
|
||||
+{
|
||||
+ return __sc_release_context(ctx, 0);
|
||||
+}
|
||||
+
|
||||
+int sc_terminate_context(sc_context_t *ctx)
|
||||
+{
|
||||
+ return __sc_release_context(ctx, 1);
|
||||
+}
|
||||
+
|
||||
int sc_set_card_driver(sc_context_t *ctx, const char *short_name)
|
||||
{
|
||||
int i = 0, match = 0;
|
||||
diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports
|
||||
index cea8d42..ed84ffe 100644
|
||||
--- a/src/libopensc/libopensc.exports
|
||||
+++ b/src/libopensc/libopensc.exports
|
||||
@@ -244,6 +244,7 @@ sc_put_data
|
||||
sc_read_binary
|
||||
sc_read_record
|
||||
sc_release_context
|
||||
+sc_terminate_context
|
||||
sc_reset
|
||||
sc_reset_retry_counter
|
||||
sc_restore_security_env
|
||||
diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h
|
||||
index ad5405d..437a14d 100644
|
||||
--- a/src/libopensc/opensc.h
|
||||
+++ b/src/libopensc/opensc.h
|
||||
@@ -374,7 +374,7 @@ struct sc_reader_operations {
|
||||
int (*init)(struct sc_context *ctx);
|
||||
/* Called when the driver is being unloaded. finish() has to
|
||||
* release any resources. */
|
||||
- int (*finish)(struct sc_context *ctx);
|
||||
+ int (*finish)(struct sc_context *ctx, unsigned after_fork);
|
||||
/* Called when library wish to detect new readers
|
||||
* should add only new readers. */
|
||||
int (*detect_readers)(struct sc_context *ctx);
|
||||
@@ -752,6 +752,12 @@ int sc_context_create(sc_context_t **ctx, const sc_context_param_t *parm);
|
||||
int sc_release_context(sc_context_t *ctx);
|
||||
|
||||
/**
|
||||
+ * Releases an established OpenSC context without releasing any state that is shared with parent process
|
||||
+ * @param ctx A pointer to the context structure to be released
|
||||
+ */
|
||||
+int sc_terminate_context(sc_context_t *ctx);
|
||||
+
|
||||
+/**
|
||||
* Detect new readers available on system.
|
||||
* @param ctx OpenSC context
|
||||
* @return SC_SUCCESS on success and an error code otherwise.
|
||||
diff --git a/src/libopensc/reader-ctapi.c b/src/libopensc/reader-ctapi.c
|
||||
index 919c3f0..e252a42 100644
|
||||
--- a/src/libopensc/reader-ctapi.c
|
||||
+++ b/src/libopensc/reader-ctapi.c
|
||||
@@ -514,7 +514,7 @@ static int ctapi_init(sc_context_t *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ctapi_finish(sc_context_t *ctx)
|
||||
+static int ctapi_finish(sc_context_t *ctx, unsigned after_fork)
|
||||
{
|
||||
struct ctapi_global_private_data *priv = (struct ctapi_global_private_data *) ctx->reader_drv_data;
|
||||
|
||||
diff --git a/src/libopensc/reader-openct.c b/src/libopensc/reader-openct.c
|
||||
index a276d52..32871d0 100644
|
||||
--- a/src/libopensc/reader-openct.c
|
||||
+++ b/src/libopensc/reader-openct.c
|
||||
@@ -29,7 +29,7 @@
|
||||
/* function declarations */
|
||||
static int openct_reader_init(sc_context_t *ctx);
|
||||
static int openct_add_reader(sc_context_t *ctx, unsigned int num, ct_info_t *info);
|
||||
-static int openct_reader_finish(sc_context_t *ctx);
|
||||
+static int openct_reader_finish(sc_context_t *ctx, unsigned after_fork);
|
||||
static int openct_reader_release(sc_reader_t *reader);
|
||||
static int openct_reader_detect_card_presence(sc_reader_t *reader);
|
||||
static int openct_reader_connect(sc_reader_t *reader);
|
||||
@@ -137,7 +137,7 @@ openct_add_reader(sc_context_t *ctx, unsigned int num, ct_info_t *info)
|
||||
* Called when the driver is being unloaded. finish() has to
|
||||
* deallocate the private data and any resources.
|
||||
*/
|
||||
-static int openct_reader_finish(sc_context_t *ctx)
|
||||
+static int openct_reader_finish(sc_context_t *ctx, unsigned after_fork)
|
||||
{
|
||||
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
|
||||
return SC_SUCCESS;
|
||||
diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c
|
||||
index 7382452..cf5890d 100644
|
||||
--- a/src/libopensc/reader-pcsc.c
|
||||
+++ b/src/libopensc/reader-pcsc.c
|
||||
@@ -740,14 +740,14 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int pcsc_finish(sc_context_t *ctx)
|
||||
+static int pcsc_finish(sc_context_t *ctx, unsigned after_fork)
|
||||
{
|
||||
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data;
|
||||
|
||||
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
|
||||
|
||||
if (gpriv) {
|
||||
- if (gpriv->pcsc_ctx != -1)
|
||||
+ if (!after_fork && gpriv->pcsc_ctx != -1)
|
||||
gpriv->SCardReleaseContext(gpriv->pcsc_ctx);
|
||||
if (gpriv->dlhandle != NULL)
|
||||
sc_dlclose(gpriv->dlhandle);
|
||||
@@ -2096,7 +2096,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int cardmod_finish(sc_context_t *ctx)
|
||||
+static int cardmod_finish(sc_context_t *ctx, unsigned after_fork)
|
||||
{
|
||||
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) ctx->reader_drv_data;
|
||||
|
||||
diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c
|
||||
index ee6cf7c..886476e 100644
|
||||
--- a/src/pkcs11/pkcs11-global.c
|
||||
+++ b/src/pkcs11/pkcs11-global.c
|
||||
@@ -40,6 +40,7 @@ list_t virtual_slots;
|
||||
pid_t initialized_pid = (pid_t)-1;
|
||||
#endif
|
||||
static int in_finalize = 0;
|
||||
+static CK_RV __sc_pkcs11_finalize(CK_VOID_PTR pReserved, unsigned after_fork);
|
||||
extern CK_FUNCTION_LIST pkcs11_function_list;
|
||||
|
||||
#if defined(HAVE_PTHREAD) && defined(PKCS11_THREAD_LOCKING)
|
||||
@@ -205,7 +206,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
|
||||
/* Handle fork() exception */
|
||||
#if !defined(_WIN32)
|
||||
if (current_pid != initialized_pid) {
|
||||
- C_Finalize(NULL_PTR);
|
||||
+ __sc_pkcs11_finalize(NULL_PTR, 1);
|
||||
}
|
||||
initialized_pid = current_pid;
|
||||
in_finalize = 0;
|
||||
@@ -271,7 +272,8 @@ out:
|
||||
return rv;
|
||||
}
|
||||
|
||||
-CK_RV C_Finalize(CK_VOID_PTR pReserved)
|
||||
+static
|
||||
+CK_RV __sc_pkcs11_finalize(CK_VOID_PTR pReserved, unsigned after_fork)
|
||||
{
|
||||
int i;
|
||||
void *p;
|
||||
@@ -292,10 +294,14 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
|
||||
|
||||
/* cancel pending calls */
|
||||
in_finalize = 1;
|
||||
- sc_cancel(context);
|
||||
- /* remove all cards from readers */
|
||||
- for (i=0; i < (int)sc_ctx_get_reader_count(context); i++)
|
||||
- card_removed(sc_ctx_get_reader(context, i));
|
||||
+
|
||||
+ if (!after_fork) {
|
||||
+ sc_cancel(context);
|
||||
+
|
||||
+ /* remove all cards from readers */
|
||||
+ for (i=0; i < (int)sc_ctx_get_reader_count(context); i++)
|
||||
+ card_removed(sc_ctx_get_reader(context, i));
|
||||
+ }
|
||||
|
||||
while ((p = list_fetch(&sessions)))
|
||||
free(p);
|
||||
@@ -307,7 +313,10 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
|
||||
}
|
||||
list_destroy(&virtual_slots);
|
||||
|
||||
- sc_release_context(context);
|
||||
+ if (after_fork)
|
||||
+ sc_terminate_context(context);
|
||||
+ else
|
||||
+ sc_release_context(context);
|
||||
context = NULL;
|
||||
|
||||
/* Release and destroy the mutex */
|
||||
@@ -316,6 +325,17 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
|
||||
return rv;
|
||||
}
|
||||
|
||||
+CK_RV C_Finalize(CK_VOID_PTR pReserved)
|
||||
+{
|
||||
+#if !defined(_WIN32)
|
||||
+ pid_t current_pid = getpid();
|
||||
+ if (current_pid != initialized_pid) {
|
||||
+ return __sc_pkcs11_finalize(NULL_PTR, 1);
|
||||
+ }
|
||||
+#endif
|
||||
+ return __sc_pkcs11_finalize(pReserved, 0);
|
||||
+}
|
||||
+
|
||||
CK_RV C_GetInfo(CK_INFO_PTR pInfo)
|
||||
{
|
||||
CK_RV rv = CKR_OK;
|
@ -20,6 +20,8 @@ Requires: pcsc-lite
|
||||
Obsoletes: mozilla-opensc-signer < 0.12.0
|
||||
Obsoletes: opensc-devel < 0.12.0
|
||||
|
||||
Patch0: opensc-0.15.0-fork-issue.patch
|
||||
|
||||
%description
|
||||
OpenSC provides a set of libraries and utilities to work with smart cards. Its
|
||||
main focus is on cards that support cryptographic operations, and facilitate
|
||||
@ -33,6 +35,8 @@ every software/card that does so, too.
|
||||
%prep
|
||||
%setup -q -n OpenSC-%{version}
|
||||
|
||||
%patch0 -p1 -b .fork-issue
|
||||
|
||||
cp -p src/pkcs15init/README ./README.pkcs15init
|
||||
cp -p src/scconf/README.scconf .
|
||||
# No {_libdir} here to avoid multilib conflicts; it's just an example
|
||||
@ -135,6 +139,7 @@ rm -rf %{buildroot}%{_sysconfdir}/bash_completion.d/
|
||||
%changelog
|
||||
* Tue Jul 14 2015 Nikos Mavrogiannopoulos <nmav@redhat.com> - 0.15.0-1
|
||||
- Update to 0.15.0 (#1209682)
|
||||
- Solve issue with C_Initialize after fork() (#1218797)
|
||||
|
||||
* Thu Jun 18 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.14.0-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
|
||||
|
Loading…
Reference in New Issue
Block a user