Skip to content

Commit

Permalink
build: Make libffi closure optional
Browse files Browse the repository at this point in the history
libffi's closure support is not available on all platforms and may fail
at run time if running under a stricter SELinux policy.  Fallback to
pre-compiled closures if it is not usable.

https://bugs.freedesktop.org/show_bug.cgi?id=97611
  • Loading branch information
ueno committed Nov 24, 2016
1 parent 1e1bdce commit dac7fa5
Show file tree
Hide file tree
Showing 10 changed files with 386 additions and 117 deletions.
19 changes: 8 additions & 11 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -195,22 +195,19 @@ if test "$with_libffi" != "no"; then
AC_SUBST(LIBFFI_CFLAGS)
AC_SUBST(LIBFFI_LIBS)

SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $LIBFFI_CFLAGS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <ffi.h>],
[ #if FFI_CLOSURES
#else
#error no closures
#endif
])],
[], [AC_MSG_ERROR([the libffi on this system has no support for closures.])])
CFLAGS="$SAVE_CFLAGS"

with_libffi="yes"
fi

AM_CONDITIONAL(WITH_FFI, test "$with_libffi" = "yes")

AC_ARG_WITH([fixed-closure],
[AS_HELP_STRING([--with-fixed-closure=integer], [Precompile fallback closures if libffi closures are not available])],
[fixed_closure=$withval],
[fixed_closure=64])

AC_DEFINE_UNQUOTED(P11_VIRTUAL_MAX_FIXED, [$fixed_closure], [The number of fallback closures compiled in])
AC_SUBST(fixed_closure)

# --------------------------------------------------------------------
# Hash implementation

Expand Down
4 changes: 0 additions & 4 deletions p11-kit/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,6 @@ print_messages_LDADD = $(p11_kit_LIBS)
frob_setuid_SOURCES = p11-kit/frob-setuid.c
frob_setuid_LDADD = $(p11_kit_LIBS)

if WITH_FFI

CHECK_PROGS += \
test-virtual \
test-managed \
Expand All @@ -226,8 +224,6 @@ test_transport_LDADD = $(p11_kit_LIBS)
test_virtual_SOURCES = p11-kit/test-virtual.c
test_virtual_LDADD = $(p11_kit_LIBS)

endif

noinst_LTLIBRARIES += \
mock-one.la \
mock-two.la \
Expand Down
157 changes: 151 additions & 6 deletions p11-kit/gen-wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,114 @@ def wrapper_function_name(self, function):
return 'binding_C_{function}'.format(function=function.name)


class FixedFunctionTemplate(FunctionTemplate):
def __init__(self):
super(FixedFunctionTemplate, self).__init__('''\
static CK_RV \\
${wrapper_function_name} (${arglist}) \\
{ \\
CK_FUNCTION_LIST *bound; \\
Wrapper *wrapper; \\
CK_X_FUNCTION_LIST *funcs; \\
bound = fixed_closures[fixed_index]; \\
return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \\
wrapper = (Wrapper *) bound; \\
funcs = &wrapper->virt->funcs; \\
return funcs->C_${function_name} (funcs, ${args}); \\
} \\
\\''')

@property
def arglist(self):
function = self.substitute_kwargs['function']
return self.format_arglist(function.args, sep=', \\\n')


class FixedFunctionListTemplate(FunctionListTemplate):
def __init__(self):
super(FixedFunctionListTemplate, self).__init__(
'''\
#define P11_VIRTUAL_FIXED_FUNCTIONS(fixed_index) \\
${function_list}
static CK_RV \\
fixed ## fixed_index ## _C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list);
#define P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(fixed_index) \\
static CK_RV \\
fixed ## fixed_index ## _C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) \\
{ \\
if (!list) \\
return CKR_ARGUMENTS_BAD; \\
*list = fixed_closures[fixed_index]; \\
return CKR_OK; \\
}
#define P11_VIRTUAL_FIXED_INITIALIZER(fixed_index) \\
{ \\
{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */ \\
${initializer_list} \\
}
${fixed_function_list}
CK_FUNCTION_LIST p11_virtual_fixed[P11_VIRTUAL_MAX_FIXED] = {
${fixed_initializer_list}
};
${fixed_get_function_list}
''',
FixedFunctionTemplate())

def wrapper_function_name(self, function):
return 'fixed ## fixed_index ## _C_{function}'.format(
function=function.name)

@property
def fixed_function_list(self):
fixed_number = self.substitute_kwargs['fixed_number']
initializers = [
'P11_VIRTUAL_FIXED_FUNCTIONS({fixed_index})'.format(
fixed_index=fixed_index)
for fixed_index in range(0, fixed_number)
]
return '\n'.join(initializers)

@property
def fixed_initializer_list(self):
fixed_number = self.substitute_kwargs['fixed_number']
initializers = [
'\tP11_VIRTUAL_FIXED_INITIALIZER({fixed_index})'.format(
fixed_index=fixed_index)
for fixed_index in range(0, fixed_number)
]
return ', \\\n'.join(initializers)

@property
def fixed_get_function_list(self):
fixed_number = self.substitute_kwargs['fixed_number']
initializers = [
'P11_VIRTUAL_FIXED_GET_FUNCTION_LIST({fixed_index})'.format(
fixed_index=fixed_index)
for fixed_index in range(0, fixed_number)
]
return '\n'.join(initializers)

def excluded_functions(self):
return ['GetFunctionList'] + list(P11_SHORT_FUNCTIONS)

@property
def initializer_list(self):
result = list()
parser = self.substitute_kwargs['parser']
for function in parser.functions:
short_function_name = P11_SHORT_FUNCTIONS.get(function.name)
if short_function_name:
result.append('\t' + short_function_name)
else:
result.append('\t' + self.wrapper_function_name(function))
return ', \\\n'.join(result)


class MaxFunctionsTemplate(Template):
def __init__(self):
super(MaxFunctionsTemplate, self).__init__('${max_functions}')
Expand All @@ -434,13 +542,9 @@ def max_args(self):
class FunctionInfoTemplate(FunctionTemplate):
def __init__(self):
super(FunctionInfoTemplate, self).__init__('''\
{ FUNCTION (${function_name}), { ${args}, NULL } },\
{ FUNCTION (${function_name}) },\
''')

def format_args(self, args, sep=', '):
l = [type_to_ffi_type(arg.type) for arg in args]
return sep.join(l).strip()


class FunctionInfoListTemplate(FunctionListTemplate):
def __init__(self):
Expand All @@ -460,6 +564,34 @@ def wrapper_function_name(self, function):
return function.name


class BindingInfoTemplate(FunctionTemplate):
def __init__(self):
super(BindingInfoTemplate, self).__init__('''\
{ binding_C_##${function_name}, { ${args}, NULL } },\
''')

def format_args(self, args, sep=', '):
l = [type_to_ffi_type(arg.type) for arg in args]
return sep.join(l).strip()


class BindingInfoListTemplate(FunctionListTemplate):
def __init__(self):
super(BindingInfoListTemplate, self).__init__(
'''\
static const BindingInfo binding_info[] = {
${function_list}
{ 0, }
};
''',
BindingInfoTemplate())

def excluded_functions(self):
return ['GetFunctionList'] + list(P11_SHORT_FUNCTIONS)

def wrapper_function_name(self, function):
return function.name

class FileTemplate(Template):
def __init__(self, infile):
super(FileTemplate, self).__init__(infile.read())
Expand All @@ -479,6 +611,11 @@ def binding_function_list(self):
template = BindingFunctionListTemplate()
return template.substitute(**self.substitute_kwargs)

@property
def fixed_function_list(self):
template = FixedFunctionListTemplate()
return template.substitute(**self.substitute_kwargs)

@property
def max_functions(self):
template = MaxFunctionsTemplate()
Expand All @@ -494,6 +631,11 @@ def function_info_list(self):
template = FunctionInfoListTemplate()
return template.substitute(**self.substitute_kwargs)

@property
def binding_info_list(self):
template = BindingInfoListTemplate()
return template.substitute(**self.substitute_kwargs)

if __name__ == '__main__':
import argparse

Expand All @@ -504,9 +646,12 @@ def function_info_list(self):
help='the pkcs11.h header file')
parser.add_argument('pkcs11i', type=argparse.FileType('r'),
help='the pkcs11i.h header file')
parser.add_argument('-n', '--fixed-number', type=int,
default=64,
help='exclude functions')
args = parser.parse_args()

parser = Parser()
parser.parse(args.pkcs11, args.pkcs11i)
template = FileTemplate(args.template)
print(template.substitute(parser=parser))
print(template.substitute(parser=parser, fixed_number=args.fixed_number))
24 changes: 6 additions & 18 deletions p11-kit/modules.c
Original file line number Diff line number Diff line change
Expand Up @@ -1758,22 +1758,11 @@ lookup_managed_option (Module *mod,
value = _p11_conf_parse_boolean (string, def_value);

if (!supported && value != supported) {
if (!p11_virtual_can_wrap ()) {
/*
* This is because libffi dependency was not built. The libffi dependency
* is highly recommended and building without it results in a large loss
* of functionality.
*/
p11_message ("the '%s' option for module '%s' is not supported on this system",
option, mod->name);
} else {
/*
* This is because the module is running in unmanaged mode, so turn off the
*/
p11_message ("the '%s' option for module '%s' is only supported for managed modules",
option, mod->name);
}
return false;
/*
* This is because the module is running in unmanaged mode, so turn off the
*/
p11_message ("the '%s' option for module '%s' is only supported for managed modules",
option, mod->name);
}

return value;
Expand All @@ -1795,7 +1784,6 @@ release_module_inlock_rentrant (CK_FUNCTION_LIST *module,
assert_not_reached ();
p11_virtual_unwrap (module);
}

/* If an unmanaged module then caller should have finalized */
} else {
mod = p11_dict_get (gl.unmanaged_by_funcs, module);
Expand Down Expand Up @@ -1855,7 +1843,7 @@ prepare_module_inlock_reentrant (Module *mod,
is_managed = false;
with_log = false;
} else {
is_managed = lookup_managed_option (mod, p11_virtual_can_wrap (), "managed", true);
is_managed = lookup_managed_option (mod, true, "managed", true);
with_log = lookup_managed_option (mod, is_managed, "log-calls", false);
}

Expand Down
2 changes: 1 addition & 1 deletion p11-kit/proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2364,7 +2364,7 @@ C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
}
}

if (rv == CKR_OK && p11_virtual_can_wrap ()) {
if (rv == CKR_OK) {
state = calloc (1, sizeof (State));
if (!state) {
rv = CKR_HOST_MEMORY;
Expand Down
12 changes: 5 additions & 7 deletions p11-kit/test-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,16 +402,14 @@ main (int argc,
p11_library_init ();

/* These only work when managed */
if (p11_virtual_can_wrap ()) {
p11_test (test_recursive_initialization, "/init/test_recursive_initialization");
p11_test (test_threaded_initialization, "/init/test_threaded_initialization");
p11_test (test_mutexes, "/init/test_mutexes");
p11_test (test_load_and_initialize, "/init/test_load_and_initialize");
p11_test (test_recursive_initialization, "/init/test_recursive_initialization");
p11_test (test_threaded_initialization, "/init/test_threaded_initialization");
p11_test (test_mutexes, "/init/test_mutexes");
p11_test (test_load_and_initialize, "/init/test_load_and_initialize");

#ifdef OS_UNIX
p11_test (test_fork_initialization, "/init/test_fork_initialization");
p11_test (test_fork_initialization, "/init/test_fork_initialization");
#endif
}

p11_test (test_initalize_fail, "/init/test_initalize_fail");
p11_test (test_finalize_fail, "/init/test_finalize_fail");
Expand Down
1 change: 0 additions & 1 deletion p11-kit/test-virtual.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ main (int argc,
mock_module_init ();
p11_library_init ();

assert (p11_virtual_can_wrap ());
p11_test (test_initialize, "/virtual/test_initialize");
p11_test (test_fall_through, "/virtual/test_fall_through");
p11_test (test_get_function_list, "/virtual/test_get_function_list");
Expand Down
5 changes: 5 additions & 0 deletions p11-kit/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include "p11-kit.h"
#include "private.h"
#include "proxy.h"
#include "virtual.h"

#include <assert.h>
#include <stdarg.h>
Expand Down Expand Up @@ -251,6 +252,7 @@ void
_p11_kit_init (void)
{
p11_library_init_once ();
p11_virtual_init_fixed ();
}

#ifdef __GNUC__
Expand All @@ -260,6 +262,7 @@ void
_p11_kit_fini (void)
{
p11_proxy_module_cleanup ();
p11_virtual_uninit_fixed ();
p11_library_uninit ();
}

Expand All @@ -277,12 +280,14 @@ DllMain (HINSTANCE instance,
switch (reason) {
case DLL_PROCESS_ATTACH:
p11_library_init ();
p11_virtual_init_fixed ();
break;
case DLL_THREAD_DETACH:
p11_library_thread_cleanup ();
break;
case DLL_PROCESS_DETACH:
p11_proxy_module_cleanup ();
p11_virtual_uninit_fixed ();
p11_library_uninit ();
break;
default:
Expand Down
Loading

0 comments on commit dac7fa5

Please sign in to comment.