On Wed, 2015-06-24 at 10:03 +0200, Nikos Mavrogiannopoulos wrote:
> This patch set eliminates two issues in the proxy module:
> 1. A process using the proxy module would crash if at some point 
> after
[...]
> The issue (1) is very tricky to debug, the reason that the crash
> happened on the parent is not clear to me (they are different 
> processes after all). The crash is in binding_C_Finalize() after 
> having passed from ffi. See the comments in 0004 for the fix.

Things became more clear when I checked libffi's dlmmap_locked() and
the trace.

22225 open("/tmp/ffitnd0s0", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
22225 unlink("/tmp/ffitnd0s0")          = 0
22225 ftruncate(3, 4096)                = 0
22225 mmap(NULL, 4096, PROT_READ|PROT_EXEC, MAP_SHARED, 3, 0) =
0x7f3282c08000
22225 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0) =
0x7f3282c07000

My understanding is that libffi allocates shared memory so a
deallocation in the child process would affect a deallocation in the
parent process. I'm not familiar with libffi, but is that the 
intended/documented behavior? Looks pretty scary.

A better/more precise fix (replacement for 0002-Do-not-finalize-modules
-created-in-another-pid.patch) is attached.

regards,
Nikos
From 42cd77396b815429d39416737605c6c93097a569 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <n...@redhat.com>
Date: Wed, 24 Jun 2015 14:45:18 +0200
Subject: [PATCH] Do not deinitialize libffi's wrapper functions in children

Libffi uses shared memory to store them, and a deallocation
in a child will cause issues for the parent.
---
 p11-kit/virtual.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/p11-kit/virtual.c b/p11-kit/virtual.c
index 2f4f0ae..84a7f2e 100644
--- a/p11-kit/virtual.c
+++ b/p11-kit/virtual.c
@@ -74,6 +74,7 @@ typedef struct {
 	/* A list of our libffi built closures, for cleanup later */
 	ffi_closure *ffi_closures[MAX_FUNCTIONS];
 	ffi_cif ffi_cifs[MAX_FUNCTIONS];
+	int forkid;
 	int ffi_used;
 } Wrapper;
 
@@ -2742,6 +2743,7 @@ p11_virtual_wrap (p11_virtual *virt,
 	wrapper->destroyer = destroyer;
 	wrapper->bound.version.major = CRYPTOKI_VERSION_MAJOR;
 	wrapper->bound.version.minor = CRYPTOKI_VERSION_MINOR;
+	wrapper->forkid = p11_forkid;
 
 	if (!init_wrapper_funcs (wrapper))
 		return_val_if_reached (NULL);
@@ -2792,7 +2794,8 @@ p11_virtual_unwrap (CK_FUNCTION_LIST_PTR module)
 	if (wrapper->destroyer)
 		(wrapper->destroyer) (wrapper->virt);
 
-	uninit_wrapper_funcs (wrapper);
+	if (wrapper->forkid == p11_forkid)
+		uninit_wrapper_funcs (wrapper);
 	free (wrapper);
 }
 
-- 
2.4.3

_______________________________________________
p11-glue mailing list
p11-glue@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/p11-glue

Reply via email to