Avoid memory leaks when initializing tokeninfo in various drivers

Thanks oss-fuzz

https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22578
This commit is contained in:
Jakub Jelen 2020-06-04 12:21:47 +02:00 committed by Frank Morgner
parent 71d1f69a3a
commit f49162af04
20 changed files with 76 additions and 88 deletions

View File

@ -1339,8 +1339,11 @@ static int coolkey_get_token_info(sc_card_t *card, sc_pkcs15_tokeninfo_t * token
serial_number = coolkey_cuid_to_string(&priv->cuid);
if (label && manufacturer_id && serial_number) {
free(token_info->label);
token_info->label = label;
free(token_info->manufacturer_id);
token_info->manufacturer_id = manufacturer_id;
free(token_info->serial_number);
token_info->serial_number = serial_number;
return SC_SUCCESS;
}

View File

@ -125,6 +125,15 @@ unsigned short lebytes2ushort(const u8 *buf);
*/
unsigned long lebytes2ulong(const u8 *buf);
/* Usable for setting string elements of token info, which
* are either initialized to NULL or we need to clean
* previous value.
*
* @param strp The pointer where to store string
* @param value The string to store (is strdupped)
*/
void set_string(char **strp, const char *value);
#define BYTES4BITS(num) (((num) + 7) / 8) /* number of bytes necessary to hold 'num' bits */
/* Returns an scconf_block entry with matching ATR/ATRmask to the ATR specified,

View File

@ -36,6 +36,7 @@
#include "common/compat_strlcpy.h"
#include "libopensc/pkcs15.h"
#include "libopensc/log.h"
#include "libopensc/internal.h"
static int (*set_security_env) (sc_card_t *, const sc_security_env_t *, int);
@ -60,13 +61,6 @@ static int do_sign(sc_card_t * card, const u8 * in, size_t inlen, u8 * out,
return card->ops->decipher(card, in, inlen, out, outlen);
}
static void set_string(char **strp, const char *value)
{
if (*strp)
free(*strp);
*strp = value ? strdup(value) : NULL;
}
#if 1
/* XXX: temporary copy of the old pkcs15emu functions,
* to be removed */

View File

@ -122,8 +122,8 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
/* could read this off card if needed */
p15card->tokeninfo->label = strdup(cac_get_name(card->type));
p15card->tokeninfo->manufacturer_id = strdup(MANU_ID);
set_string(&p15card->tokeninfo->label, cac_get_name(card->type));
set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID);
/*
* get serial number
@ -131,10 +131,10 @@ static int sc_pkcs15emu_cac_init(sc_pkcs15_card_t *p15card)
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
if (r < 0) {
sc_log(card->ctx, "sc_card_ctl rc=%d",r);
p15card->tokeninfo->serial_number = strdup("00000000");
set_string(&p15card->tokeninfo->serial_number, "00000000");
} else {
sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0);
p15card->tokeninfo->serial_number = strdup(buf);
set_string(&p15card->tokeninfo->serial_number, buf);
}
/* set pins */

View File

@ -497,9 +497,9 @@ static int sc_pkcs15emu_coolkey_init(sc_pkcs15_card_t *p15card)
r = sc_card_ctl(card, SC_CARDCTL_COOLKEY_GET_TOKEN_INFO, p15card->tokeninfo);
if (r < 0) {
/* put some defaults in if we didn't succeed */
p15card->tokeninfo->label = strdup("Coolkey");
p15card->tokeninfo->manufacturer_id = strdup("Unknown");
p15card->tokeninfo->serial_number = strdup("00000000");
set_string(&p15card->tokeninfo->label, "Coolkey");
set_string(&p15card->tokeninfo->manufacturer_id, "Unknown");
set_string(&p15card->tokeninfo->serial_number, "00000000");
}
/* set pins */

View File

@ -45,8 +45,8 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
size_t field_length = 0, modulus_length = 0;
sc_path_t tmppath;
p15card->tokeninfo->label = strdup("ID-kaart");
p15card->tokeninfo->manufacturer_id = strdup("AS Sertifitseerimiskeskus");
set_string(&p15card->tokeninfo->label, "ID-kaart");
set_string(&p15card->tokeninfo->manufacturer_id, "AS Sertifitseerimiskeskus");
/* Select application directory */
sc_format_path ("3f00eeee5044", &tmppath);
@ -57,7 +57,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
r = sc_read_record (card, SC_ESTEID_PD_DOCUMENT_NR, buff, sizeof(buff), SC_RECORD_BY_REC_NR);
LOG_TEST_RET(card->ctx, r, "read document number failed");
buff[MIN((size_t) r, (sizeof buff)-1)] = '\0';
p15card->tokeninfo->serial_number = strdup((const char *)buff);
set_string(&p15card->tokeninfo->serial_number, (const char *)buff);
p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION
| SC_PKCS15_TOKEN_EID_COMPLIANT

View File

@ -33,12 +33,6 @@
#include "opensc.h"
#include "pkcs15.h"
static void set_string(char **strp, const char *value) {
if (*strp)
free(*strp);
*strp = value ? strdup(value) : NULL;
}
static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) {
sc_card_t *card = p15card->card;
u8 buff[11];
@ -61,6 +55,7 @@ static int sc_pkcs15emu_esteid2018_init(sc_pkcs15_card_t *p15card) {
for (j = 0; j < taglen; j++)
if (!isalnum(tag[j]))
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
free(p15card->tokeninfo->serial_number);
p15card->tokeninfo->serial_number = malloc(taglen + 1);
if (!p15card->tokeninfo->serial_number)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);

View File

@ -219,8 +219,8 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
/* could read this off card if needed */
p15card->tokeninfo->label = strdup("GemSAFE");
p15card->tokeninfo->manufacturer_id = strdup(MANU_ID);
set_string(&p15card->tokeninfo->label, "GemSAFE");
set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID);
/* get serial number */
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
if (r != SC_SUCCESS)
@ -228,7 +228,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0);
if (r != SC_SUCCESS)
return SC_ERROR_INTERNAL;
p15card->tokeninfo->serial_number = strdup(buf);
set_string(&p15card->tokeninfo->serial_number, buf);
/* test if we have a gemsafe app df */
memset(&path, 0, sizeof(path));

View File

@ -127,6 +127,7 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card)
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, NULL);
LOG_TEST_RET(card->ctx, r, "unable to get the serial number. Uninitialized card ?");
free(p15card->tokeninfo->serial_number);
p15card->tokeninfo->serial_number = (char*) malloc(card->serialnr.len *2 +1);
if (!p15card->tokeninfo->serial_number) {
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);

View File

@ -68,8 +68,8 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card)
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
/* could read this off card if needed */
p15card->tokeninfo->label = strdup("IDPrime");
p15card->tokeninfo->manufacturer_id = strdup("Gemalto");
set_string(&p15card->tokeninfo->label, "IDPrime");
set_string(&p15card->tokeninfo->manufacturer_id, "Gemalto");
/*
* get serial number
@ -78,10 +78,10 @@ static int sc_pkcs15emu_idprime_init(sc_pkcs15_card_t *p15card)
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
if (r < 0) {
sc_log(card->ctx, "sc_card_ctl rc=%d", r);
p15card->tokeninfo->serial_number = strdup("00000000");
set_string(&p15card->tokeninfo->serial_number, "00000000");
} else {
sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0);
p15card->tokeninfo->serial_number = strdup(buf);
set_string(&p15card->tokeninfo->serial_number, buf);
}
/* set pin */
sc_log(card->ctx, "IDPrime adding pin...");

View File

@ -168,13 +168,6 @@ static const struct {
* Utility functions
*/
static void set_string(char **strp, const char *value)
{
if (*strp)
free(*strp);
*strp = value ? strdup(value) : NULL;
}
static int loadFile(const sc_pkcs15_card_t *p15card, const sc_path_t *path,
u8 *buf, const size_t buflen)
{

View File

@ -42,10 +42,10 @@ sc_pkcs15emu_jpki_init(sc_pkcs15_card_t * p15card)
LOG_FUNC_CALLED(p15card->card->ctx);
p15card->tokeninfo->label = strdup("JPKI");
p15card->tokeninfo->manufacturer_id = strdup("JPKI");
set_string(&p15card->tokeninfo->label, "JPKI");
set_string(&p15card->tokeninfo->manufacturer_id, "JPKI");
/* set dummy until we found serial number */
p15card->tokeninfo->serial_number = strdup("00000000");
set_string(&p15card->tokeninfo->serial_number, "00000000");
/* Select application directory */
if (drvdata->selected != SELECT_JPKI_AP) {

View File

@ -357,8 +357,8 @@ sc_oberthur_parse_tokeninfo (struct sc_pkcs15_card *p15card,
flags = *(buff + 0x22) * 0x100 + *(buff + 0x23);
p15card->tokeninfo->label = strdup(label);
p15card->tokeninfo->manufacturer_id = strdup("Oberthur/OpenSC");
set_string(&p15card->tokeninfo->label, label);
set_string(&p15card->tokeninfo->manufacturer_id, "Oberthur/OpenSC");
if (flags & 0x01)
p15card->tokeninfo->flags |= SC_PKCS15_TOKEN_PRN_GENERATION;
@ -919,7 +919,7 @@ sc_pkcs15emu_oberthur_init(struct sc_pkcs15_card * p15card)
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
sc_bin_to_hex(card->serialnr.value, card->serialnr.len, serial, sizeof(serial), 0);
p15card->tokeninfo->serial_number = strdup(serial);
set_string(&p15card->tokeninfo->serial_number, serial);
p15card->ops.parse_df = sc_awp_parse_df;
p15card->ops.clear = sc_awp_clear;

View File

@ -132,15 +132,6 @@ static const pgp_manuf_map_t manuf_map[] = {
{ 0, NULL }
};
static void
set_string(char **strp, const char *value)
{
if (*strp)
free(*strp);
*strp = value? strdup(value) : NULL;
}
/*
* This function pretty much follows what find_tlv in the GNUpg
* code does.

View File

@ -620,8 +620,8 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
/* could read this off card if needed */
/* CSP does not like a - in the name */
p15card->tokeninfo->label = strdup("PIV_II");
p15card->tokeninfo->manufacturer_id = strdup(MANU_ID);
set_string(&p15card->tokeninfo->label, "PIV_II");
set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID);
/*
* get serial number
@ -633,10 +633,10 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
if (r < 0) {
sc_log(card->ctx, "sc_card_ctl rc=%d",r);
p15card->tokeninfo->serial_number = strdup("00000000");
set_string(&p15card->tokeninfo->serial_number, "00000000");
} else {
sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0);
p15card->tokeninfo->serial_number = strdup(buf);
set_string(&p15card->tokeninfo->serial_number, buf);
}
/* US gov issued PIVs have CHUID with a FASCN that does not start with 9999 */
if (serial.len == 25 && !(serial.value[0] == 0xD4 && serial.value[1] == 0xE7 && serial.value[2] == 0x39 && (serial.value[3] | 0x7F) == 0xFF)) {

View File

@ -940,6 +940,7 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
assert(len >= 8);
len -= 5;
free(p15card->tokeninfo->serial_number);
p15card->tokeninfo->serial_number = calloc(len + 1, 1);
if (p15card->tokeninfo->serial_number == NULL)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);

View File

@ -320,15 +320,11 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card)
if (r != SC_SUCCESS)
return r;
/* set card label */
if (p15card->tokeninfo->label != NULL)
free(p15card->tokeninfo->label);
p15card->tokeninfo->label = strdup(TC_CARDOS_LABEL);
set_string(&p15card->tokeninfo->label, TC_CARDOS_LABEL);
if (p15card->tokeninfo->label == NULL)
return SC_ERROR_OUT_OF_MEMORY;
/* set the manufacturer ID */
if (p15card->tokeninfo->manufacturer_id != NULL)
free(p15card->tokeninfo->manufacturer_id);
p15card->tokeninfo->manufacturer_id = strdup(MANU_ID);
set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID);
if (p15card->tokeninfo->manufacturer_id == NULL)
return SC_ERROR_OUT_OF_MEMORY;
/* set the serial number */
@ -336,7 +332,7 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card)
if (r != SC_SUCCESS || iccsn.len < 5+8)
return SC_ERROR_INTERNAL;
sc_bin_to_hex(iccsn.value + 5, 8, hex_buf, sizeof(hex_buf), 0);
p15card->tokeninfo->serial_number = strdup(hex_buf);
set_string(&p15card->tokeninfo->serial_number, hex_buf);
if (p15card->tokeninfo->serial_number == NULL)
return SC_ERROR_OUT_OF_MEMORY;
/* select the application DF */

View File

@ -287,8 +287,8 @@ static int detect_netkey(
sprintf(dir,"%04X", f->id);
sc_file_free(f);
p15card->tokeninfo->manufacturer_id = strdup("TeleSec GmbH");
p15card->tokeninfo->label = strdup(card->type==SC_CARD_TYPE_TCOS_V3 ? "NetKey V3 Card" : "NetKey Card");
set_string(&p15card->tokeninfo->manufacturer_id, "TeleSec GmbH");
set_string(&p15card->tokeninfo->label, card->type==SC_CARD_TYPE_TCOS_V3 ? "NetKey V3 Card" : "NetKey Card");
keylen= card->type==SC_CARD_TYPE_TCOS_V3 ? 2048 : 1024;
c_auth= card->type==SC_CARD_TYPE_TCOS_V3 ? "C500" : "C100";
@ -375,8 +375,8 @@ static int detect_idkey(
memcpy(p.value, "\xD2\x76\x00\x00\x03\x0C\x01", p.len=7);
if (sc_select_file(card,&p,NULL)!=SC_SUCCESS) return 1;
p15card->tokeninfo->manufacturer_id = strdup("TeleSec GmbH");
p15card->tokeninfo->label = strdup("IDKey Card");
set_string(&p15card->tokeninfo->manufacturer_id, "TeleSec GmbH");
set_string(&p15card->tokeninfo->label, "IDKey Card");
insert_cert(p15card, "DF074331", 0x45, 1, "Signatur Zertifikat 1");
insert_cert(p15card, "DF074332", 0x46, 1, "Signatur Zertifikat 2");
@ -407,8 +407,8 @@ static int detect_signtrust(
sc_pkcs15_card_t *p15card
){
if(insert_cert(p15card,"8000DF01C000", 0x45, 1, "Signatur Zertifikat")) return 1;
p15card->tokeninfo->manufacturer_id = strdup("Deutsche Post");
p15card->tokeninfo->label = strdup("SignTrust Card");
set_string(&p15card->tokeninfo->manufacturer_id, "Deutsche Post");
set_string(&p15card->tokeninfo->label, "SignTrust Card");
insert_cert(p15card,"800082008220", 0x46, 1, "Verschluesselungs Zertifikat");
insert_cert(p15card,"800083008320", 0x47, 1, "Authentifizierungs Zertifikat");
@ -437,8 +437,8 @@ static int detect_datev(
sc_pkcs15_card_t *p15card
){
if(insert_cert(p15card,"3000C500", 0x45, 0, "Signatur Zertifikat")) return 1;
p15card->tokeninfo->manufacturer_id = strdup("DATEV");
p15card->tokeninfo->label = strdup("DATEV Classic");
set_string(&p15card->tokeninfo->manufacturer_id, "DATEV");
set_string(&p15card->tokeninfo->label, "DATEV Classic");
insert_cert(p15card,"DF02C200", 0x46, 0, "Verschluesselungs Zertifikat");
insert_cert(p15card,"DF02C500", 0x47, 0, "Authentifizierungs Zertifikat");
@ -458,8 +458,8 @@ static int detect_unicard(
sc_pkcs15_card_t *p15card
){
if(!insert_cert(p15card,"41004352", 0x45, 1, "Zertifikat 1")){
p15card->tokeninfo->manufacturer_id = strdup("JLU Giessen");
p15card->tokeninfo->label = strdup("JLU Giessen Card");
set_string(&p15card->tokeninfo->manufacturer_id, "JLU Giessen");
set_string(&p15card->tokeninfo->label, "JLU Giessen Card");
insert_cert(p15card,"41004353", 0x46, 1, "Zertifikat 2");
insert_cert(p15card,"41004354", 0x47, 1, "Zertifikat 3");
@ -468,8 +468,8 @@ static int detect_unicard(
insert_key(p15card,"41005105", 0x47, 0x85, 1024, 1, "Schluessel 3");
} else if(!insert_cert(p15card,"41014352", 0x45, 1, "Zertifikat 1")){
p15card->tokeninfo->manufacturer_id = strdup("TU Darmstadt");
p15card->tokeninfo->label = strdup("TUD Card");
set_string(&p15card->tokeninfo->manufacturer_id, "TU Darmstadt");
set_string(&p15card->tokeninfo->label, "TUD Card");
insert_cert(p15card,"41014353", 0x46, 1, "Zertifikat 2");
insert_cert(p15card,"41014354", 0x47, 1, "Zertifikat 3");
@ -511,7 +511,7 @@ int sc_pkcs15emu_tcos_init_ex(
}
sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0);
serial[19] = '\0';
p15card->tokeninfo->serial_number = strdup(serial);
set_string(&p15card->tokeninfo->serial_number, serial);
if(!detect_netkey(p15card)) return SC_SUCCESS;
if(!detect_idkey(p15card)) return SC_SUCCESS;

View File

@ -220,6 +220,7 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
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);
ti->serial_number = malloc(serial_len * 2 + 1);
if (ti->serial_number == NULL)
return SC_ERROR_OUT_OF_MEMORY;
@ -732,18 +733,12 @@ sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
if (!tokeninfo)
return;
if (tokeninfo->label != NULL)
free(tokeninfo->label);
if (tokeninfo->serial_number != NULL)
free(tokeninfo->serial_number);
if (tokeninfo->manufacturer_id != NULL)
free(tokeninfo->manufacturer_id);
if (tokeninfo->last_update.gtime != NULL)
free(tokeninfo->last_update.gtime);
if (tokeninfo->preferred_language != NULL)
free(tokeninfo->preferred_language);
if (tokeninfo->profile_indication.name != NULL)
free(tokeninfo->profile_indication.name);
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++)

View File

@ -237,6 +237,16 @@ unsigned long lebytes2ulong(const u8 *buf)
| (unsigned long)buf[0];
}
void set_string(char **strp, const char *value)
{
if (strp == NULL) {
return;
}
free(*strp);
*strp = value ? strdup(value) : NULL;
}
void sc_init_oid(struct sc_object_id *oid)
{
int ii;