From 00e02359a36a9decfd3ca15a194daa8ecabac8ce Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 14 Dec 2011 13:14:14 +0100 Subject: [PATCH] libopensc: Add 'paranoid-memory' setting for behavior when mlock() fails * Setting paranoid-memory to true, and mlock() fails, then allocations which require non-pageable memory will return NULL --- etc/opensc.conf.in | 9 +++++++++ src/libopensc/ctx.c | 4 ++++ src/libopensc/opensc.h | 1 + src/libopensc/sc.c | 16 +++++++++++++--- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 29871d13..07711780 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -28,6 +28,15 @@ app default { # # profile_dir = @pkgdatadir@; + # Paranoid memory allocation. + # + # If set to 'true', then refuse to continue when locking of non-pageable + # memory fails. This can cause subtle failures but is more secure when + # you have a swap disk. + # Default: false + # + # paranoid_memory = false; + # CT-API module configuration. reader_driver ctapi { # module /usr/local/towitoko/lib/libtowitoko.so { diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index b8ed8cdd..cd32cd33 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -180,6 +180,7 @@ static void set_defaults(sc_context_t *ctx, struct _sc_ctx_options *opts) if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) fclose(ctx->debug_file); ctx->debug_file = stderr; + ctx->paranoid_memory = 0; #ifdef __APPLE__ /* Override the default debug log for OpenSC.tokend to be different from PKCS#11. * TODO: Could be moved to OpenSC.tokend */ @@ -230,6 +231,9 @@ static int load_parameters(sc_context_t *ctx, scconf_block *block, if (val) sc_ctx_log_to_file(ctx, val); + ctx->paranoid_memory = scconf_get_bool (block, "paranoid-memory", + ctx->paranoid_memory); + val = scconf_get_str(block, "force_card_driver", NULL); if (val) { if (opts->forced_card_driver) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 8d9d18db..aea860d7 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -603,6 +603,7 @@ typedef struct sc_context { scconf_block *conf_blocks[3]; char *app_name; int debug; + int paranoid_memory; FILE *debug_file; char *preferred_language; diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index d6f14406..25509b86 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -701,16 +701,26 @@ int _sc_parse_atr(sc_reader_t *reader) void *sc_mem_alloc_secure(sc_context_t *ctx, size_t len) { void *pointer; - + int locked = 0; + pointer = calloc(len, sizeof(unsigned char)); if (!pointer) return NULL; #ifdef HAVE_SYS_MMAN_H /* TODO Windows support and mprotect too */ /* Do not swap the memory */ - if (mlock(pointer, len) == -1) - sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, pin may be paged to disk"); + if (mlock(pointer, len) >= 0) + locked = 1; #endif + if (!locked) { + if (ctx->paranoid_memory) { + sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, failing allocation because paranoid set"); + free (pointer); + pointer = NULL; + } else { + sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, sensitive data may be paged to disk"); + } + } return pointer; }