tools: fix segfault with verbose log into 'stderr'

Issue #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.

closes #910
This commit is contained in:
Viktor Tarasov 2016-11-23 11:24:41 +01:00
parent f6a5885348
commit f0f453781e
4 changed files with 34 additions and 25 deletions

View File

@ -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.

View File

@ -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;
@ -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)
@ -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))

View File

@ -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)
@ -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;
}
@ -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, ...)
@ -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);

View File

@ -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;