Skip to content

Commit

Permalink
tools: fix segfault with verbose log into 'stderr'
Browse files Browse the repository at this point in the history
Issue OpenSC#824

In Windows, file handles (including 'stderr', 'stdout') can not be shared
between DLL-s, and so, the log handle (File *), defined in one module, cannot
be reused in another.

That is the situation when, for example, the SM is processed
in external, dynamically loadable module as it currently implemented for
IAS/ECC card.

That's for the configuration option 're-open of log file on each message' was
introduced.

This 're-open' logic has not been tested in the particular case of opensc-*
tools used with verbose log into 'stderr' -- in dynamically loaded module the
'stderr' handle, defined in the 'main' module, was not recognized as 'stderr'
and there was an attempt to close it.
  • Loading branch information
viktorTarasov committed Nov 23, 2016
1 parent 3cb24eb commit 4ad5d1f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 25 deletions.
12 changes: 6 additions & 6 deletions etc/opensc.conf.in
Expand Up @@ -21,14 +21,14 @@ app default {
#
# debug_file = @DEBUG_FILE@

# Re-open debug file (used in WIN32)
# Reopen debug file at the every debug message.
#
# In Windows, file handles can not be shared between DLL-s,
# each DLL has a separate file handle table.
# For that reason reopen debug file before every debug message.
# For Windows it's forced to 'true'. The reason is that
# in Windows file handles can not be shared between DLL-s,
# each DLL has a separate file handle table.
#
# Default: true
# reopen_debug_file = false;
# Default: false
# reopen_debug_file = true;

# PKCS#15 initialization / personalization
# profiles directory for pkcs15-init.
Expand Down
24 changes: 19 additions & 5 deletions src/libopensc/ctx.c
Expand Up @@ -283,6 +283,17 @@ int sc_ctx_log_to_file(sc_context_t *ctx, const char* filename)
ctx->debug_file = NULL;
}

if (ctx->reopen_log_file) {
if (!ctx->debug_filename) {
if (!filename)
filename = "stderr";
ctx->debug_filename = strdup(filename);
}
}

if (!filename)
return SC_SUCCESS;

/* Handle special names */
if (!strcmp(filename, "stdout"))
ctx->debug_file = stdout;
Expand All @@ -304,13 +315,16 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *
const scconf_list *list;
const char *val, *s_internal = "internal";
int debug;
int reopen;
#ifdef _WIN32
char expanded_val[PATH_MAX];
DWORD expanded_len;
#endif

reopen = scconf_get_bool(block, "reopen_debug_file", 1);
#ifdef _WIN32
ctx->reopen_log_file = 1;
#else
ctx->reopen_log_file = scconf_get_bool(block, "reopen_debug_file", 0);
#endif

debug = scconf_get_int(block, "debug", ctx->debug);
if (debug > ctx->debug)
Expand All @@ -324,11 +338,11 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *
if (expanded_len > 0)
val = expanded_val;
#endif
if (reopen)
ctx->debug_filename = strdup(val);

sc_ctx_log_to_file(ctx, val);
}
else if (ctx->debug) {
sc_ctx_log_to_file(ctx, NULL);
}

if (scconf_get_bool (block, "paranoid-memory",
ctx->flags & SC_CTX_FLAG_PARANOID_MEMORY))
Expand Down
22 changes: 8 additions & 14 deletions src/libopensc/log.c
Expand Up @@ -112,13 +112,11 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin
if (r < 0)
return;

#ifdef _WIN32
if (ctx->debug_filename) {
if (ctx->reopen_log_file) {
r = sc_ctx_log_to_file(ctx, ctx->debug_filename);
if (r < 0)
return;
}
#endif

outf = ctx->debug_file;
if (outf == NULL)
Expand All @@ -130,15 +128,11 @@ static void sc_do_log_va(sc_context_t *ctx, int level, const char *file, int lin
fprintf(outf, "\n");
fflush(outf);

#ifdef _WIN32
if (ctx->debug_filename) {
if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) {
if (ctx->reopen_log_file) {
if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout))
fclose(ctx->debug_file);
ctx->debug_file = NULL;
}
ctx->debug_file = NULL;
}
#endif


return;
}
Expand All @@ -147,9 +141,9 @@ void _sc_debug(struct sc_context *ctx, int level, const char *format, ...)
{
va_list ap;

va_start(ap, format);
sc_do_log_va(ctx, level, NULL, 0, NULL, format, ap);
va_end(ap);
va_start(ap, format);
sc_do_log_va(ctx, level, NULL, 0, NULL, format, ap);
va_end(ap);
}

void _sc_log(struct sc_context *ctx, const char *format, ...)
Expand All @@ -162,7 +156,7 @@ void _sc_log(struct sc_context *ctx, const char *format, ...)
}

void _sc_debug_hex(sc_context_t *ctx, int type, const char *file, int line,
const char *func, const char *label, const u8 *data, size_t len)
const char *func, const char *label, const u8 *data, size_t len)
{
size_t blen = len * 5 + 128;
char *buf = malloc(blen);
Expand Down
1 change: 1 addition & 0 deletions src/libopensc/opensc.h
Expand Up @@ -679,6 +679,7 @@ typedef struct sc_context {
scconf_block *conf_blocks[3];
char *app_name;
int debug;
int reopen_log_file;
unsigned long flags;

FILE *debug_file;
Expand Down

0 comments on commit 4ad5d1f

Please sign in to comment.