From 475ce71453080c190ffddaba38d04fe6c8d43087 Mon Sep 17 00:00:00 2001 From: Viktor Tarasov Date: Thu, 7 May 2015 21:55:26 +0200 Subject: [PATCH] iasecc: fixed resource leak pkcs15-iasecc: fix memory leakage iasecc: fix memory leakage --- src/libopensc/card-iasecc.c | 10 +++++++-- src/pkcs15init/pkcs15-iasecc.c | 37 +++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c index 43974897..09d730d6 100644 --- a/src/libopensc/card-iasecc.c +++ b/src/libopensc/card-iasecc.c @@ -1501,12 +1501,18 @@ iasecc_se_cache_info(struct sc_card *card, struct iasecc_se_info *se) if (card->cache.valid && card->cache.current_df) { sc_file_dup(&se_info->df, card->cache.current_df); - if (se_info->df == NULL) + if (se_info->df == NULL) { + free(se_info); LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file"); + } } rv = iasecc_docp_copy(ctx, &se->docp, &se_info->docp); - LOG_TEST_RET(ctx, rv, "Cannot make copy of DOCP"); + if (rv < 0) { + free(se_info->df); + free(se_info); + LOG_TEST_RET(ctx, rv, "Cannot make copy of DOCP"); + } if (!prv->se_info) { prv->se_info = se_info; diff --git a/src/pkcs15init/pkcs15-iasecc.c b/src/pkcs15init/pkcs15-iasecc.c index 5f9e8955..a7571123 100644 --- a/src/pkcs15init/pkcs15-iasecc.c +++ b/src/pkcs15init/pkcs15-iasecc.c @@ -398,8 +398,11 @@ iasecc_sdo_set_key_acls_from_profile(struct sc_profile *profile, struct sc_card scb[cntr++] = 0x00; } else if (acl->method == SC_AC_SEN || acl->method == SC_AC_PRO || acl->method == SC_AC_AUT) { - if ((acl->key_ref & 0xF) == 0 || (acl->key_ref & 0xF) == 0xF) + if ((acl->key_ref & 0xF) == 0 || (acl->key_ref & 0xF) == 0xF) { + if (file) + sc_file_free(file); LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SE reference"); + } amb |= mask; @@ -411,10 +414,15 @@ iasecc_sdo_set_key_acls_from_profile(struct sc_profile *profile, struct sc_card scb[cntr++] = acl->key_ref | IASECC_SCB_METHOD_EXT_AUTH; } else { + if (file) + sc_file_free(file); LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Unknown SCB method"); } } + if (file) + sc_file_free(file); + /* Copy ACLs into the DOCP*/ sdo->docp.acls_contact.tag = IASECC_DOCP_TAG_ACLS_CONTACT; sdo->docp.acls_contact.size = cntr + 1; @@ -606,9 +614,12 @@ iasecc_sdo_convert_to_file(struct sc_card *card, struct iasecc_sdo *sdo, struct unsigned op_method, op_ref; rv = iasecc_sdo_convert_acl(card, sdo, ops[ii], &op_method, &op_ref); - LOG_TEST_RET(ctx, rv, "IasEcc: cannot convert ACL"); - sc_log(ctx, "ii:%i, method:%X, ref:%X", ii, op_method, op_ref); + if (rv < 0) { + sc_file_free(file); + LOG_TEST_RET(ctx, rv, "IasEcc: cannot convert ACL"); + } + sc_log(ctx, "ii:%i, method:%X, ref:%X", ii, op_method, op_ref); sc_file_add_acl_entry(file, ops[ii], op_method, op_ref); } } @@ -833,17 +844,18 @@ iasecc_sdo_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card, if (!sdo_prvkey && !sdo_pubkey) LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "At least one SDO has to be supplied"); + rv = iasecc_sdo_convert_to_file(card, sdo_prvkey ? sdo_prvkey : sdo_pubkey, &dummy_file); LOG_TEST_RET(ctx, rv, "Cannot convert SDO PRIVATE KEY to file"); card->caps &= ~SC_CARD_CAP_USE_FCI_AC; rv = sc_pkcs15init_authenticate(profile, p15card, dummy_file, SC_AC_OP_UPDATE); card->caps = caps; - LOG_TEST_RET(ctx, rv, "SDO PRIVATE KEY UPDATE authentication failed"); - if (dummy_file) sc_file_free(dummy_file); + LOG_TEST_RET(ctx, rv, "SDO PRIVATE KEY UPDATE authentication failed"); + memset(&update, 0, sizeof(update)); update.sdo_prv_key = sdo_prvkey; @@ -1276,16 +1288,23 @@ iasecc_pkcs15_delete_sdo (struct sc_profile *profile, struct sc_pkcs15_card *p15 sc_log(ctx, "iasecc_pkcs15_delete_sdo() SDO class 0x%X, ref 0x%X", sdo->sdo_class, sdo->sdo_ref); rv = iasecc_sdo_convert_to_file(card, sdo, &dummy_file); - LOG_TEST_RET(ctx, rv, "iasecc_pkcs15_delete_sdo() Cannot convert SDO to file"); + if (rv < 0) { + iasecc_sdo_free(card, sdo); + LOG_TEST_RET(ctx, rv, "iasecc_pkcs15_delete_sdo() Cannot convert SDO to file"); + } card->caps &= ~SC_CARD_CAP_USE_FCI_AC; rv = sc_pkcs15init_authenticate(profile, p15card, dummy_file, SC_AC_OP_UPDATE); card->caps = save_card_caps; - LOG_TEST_RET(ctx, rv, "iasecc_pkcs15_delete_sdo() UPDATE authentication failed for SDO"); if (dummy_file) sc_file_free(dummy_file); + if (rv < 0) { + iasecc_sdo_free(card, sdo); + LOG_TEST_RET(ctx, rv, "iasecc_pkcs15_delete_sdo() UPDATE authentication failed for SDO"); + } + if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR) { /* Oberthur's card supports creation/deletion of the key slots ... */ rv = sc_card_ctl(card, SC_CARDCTL_IASECC_SDO_DELETE, sdo); @@ -1309,7 +1328,6 @@ iasecc_pkcs15_delete_sdo (struct sc_profile *profile, struct sc_pkcs15_card *p15 /* Don't know why, but, clean public key do not working with Gemalto card */ rv = iasecc_sdo_store_key(profile, p15card, sdo, NULL, &rsa); - LOG_TEST_RET(ctx, rv, "iasecc_pkcs15_delete_sdo() store empty private key failed"); } iasecc_sdo_free(card, sdo); @@ -1322,7 +1340,7 @@ iasecc_pkcs15_delete_object (struct sc_profile *profile, struct sc_pkcs15_card * struct sc_pkcs15_object *object, const struct sc_path *path) { struct sc_context *ctx = p15card->card->ctx; - struct sc_file *file = sc_file_new(); + struct sc_file *file = NULL; int rv, key_ref; LOG_FUNC_CALLED(ctx); @@ -1364,6 +1382,7 @@ iasecc_pkcs15_delete_object (struct sc_profile *profile, struct sc_pkcs15_card * LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED); } + file = sc_file_new(); file->type = SC_FILE_TYPE_WORKING_EF; file->ef_structure = SC_FILE_EF_TRANSPARENT; file->id = path->value[path->len-2] * 0x100 + path->value[path->len-1];