From 3ffe24cfb63062ad8734e1bd0b6009204a15851b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 30 Nov 2020 15:52:26 +0100 Subject: [PATCH] pkcs15: Clean tokeninfo on parse errors to avoid memory leaks Thanks oss-fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27779 --- src/libopensc/pkcs15.c | 47 +++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 41d500ef..8e661152 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -130,6 +130,7 @@ static void sc_pkcs15_remove_dfs(struct sc_pkcs15_card *); static void sc_pkcs15_remove_objects(struct sc_pkcs15_card *); static int sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *, const struct sc_pkcs15_object *, unsigned, unsigned char *, size_t *); +static void sc_pkcs15_clear_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo); int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti, const u8 *buf, size_t blen) @@ -217,7 +218,11 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, sc_format_asn1_entry(asn1_tokeninfo, asn1_toki_attrs, NULL, 0); r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL); - LOG_TEST_RET(ctx, r, "ASN.1 parsing of EF(TokenInfo) failed"); + if (r != SC_SUCCESS) { + /* The decoding could have allocated something we need to free */ + sc_pkcs15_clear_tokeninfo(ti); + LOG_TEST_RET(ctx, r, "ASN.1 parsing of EF(TokenInfo) failed"); + } if (asn1_toki_attrs[1].flags & SC_ASN1_PRESENT && serial_len > 0) { free(ti->serial_number); @@ -726,6 +731,32 @@ sc_pkcs15_tokeninfo_new(void) return tokeninfo; } +static void +sc_pkcs15_clear_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo) +{ + if (!tokeninfo) + return; + + free(tokeninfo->label); + tokeninfo->label = NULL; + free(tokeninfo->serial_number); + tokeninfo->serial_number = NULL; + free(tokeninfo->manufacturer_id); + tokeninfo->manufacturer_id = NULL; + free(tokeninfo->last_update.gtime); + tokeninfo->last_update.gtime = NULL; + free(tokeninfo->preferred_language); + tokeninfo->preferred_language = NULL; + free(tokeninfo->profile_indication.name); + tokeninfo->profile_indication.name = NULL; + if (tokeninfo->seInfo != NULL) { + unsigned i; + for (i = 0; i < tokeninfo->num_seInfo; i++) + free(tokeninfo->seInfo[i]); + free(tokeninfo->seInfo); + tokeninfo->seInfo = NULL; + } +} void sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo) @@ -733,22 +764,10 @@ sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo) if (!tokeninfo) return; - free(tokeninfo->label); - free(tokeninfo->serial_number); - free(tokeninfo->manufacturer_id); - free(tokeninfo->last_update.gtime); - free(tokeninfo->preferred_language); - free(tokeninfo->profile_indication.name); - if (tokeninfo->seInfo != NULL) { - unsigned i; - for (i = 0; i < tokeninfo->num_seInfo; i++) - free(tokeninfo->seInfo[i]); - free(tokeninfo->seInfo); - } + sc_pkcs15_clear_tokeninfo(tokeninfo); free(tokeninfo); } - void sc_pkcs15_free_app(struct sc_pkcs15_card *p15card) {