fix memory leak and read after free

Example code:
int main()
{
	...
	r = C_Initialize(NULL);
	assert(r == CKR_OK);
	r = C_GetSlotList(CK_TRUE, NULL_PTR, &slot_cnt);
	assert(r == CKR_OK);
	assert(slot_cnt >= 1);
	r = C_GetSlotList(TRUE, &slot, &slot_cnt);
	assert(r == CKR_OK);
	r = C_OpenSession(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, 0, 0, &hndl_session);
	assert(r == CKR_OK);
	assert(hndl_session != CK_INVALID_HANDLE);
	r = C_Login(hndl_session, CKU_USER, pin, sizeof(pin));
	assert(r == CKR_OK);
	r = C_CreateObject(hndl_session, data_tmpl,
			sizeof(data_tmpl)/sizeof(data_tmpl[0]), &hndl);
	assert(r == CKR_OK);
	r = C_DestroyObject(hndl_session, hndl);
	assert(r == CKR_OK);

	r = C_GenerateKeyPair(hndl_session, &rsa_genkp_mech, rsa_pbkey_tmpl,
			sizeof(rsa_pbkey_tmpl)/sizeof(rsa_pbkey_tmpl[0]), rsa_prkey_tmpl,
			sizeof(rsa_prkey_tmpl)/sizeof(rsa_prkey_tmpl[0]),
			&hndl_pb, &hndl_pr);
	assert(r == CKR_OK);

	r = C_Finalize(NULL);
	assert(r == CKR_OK);
	return 0;
}

==20626== Invalid read of size 4
==20626==    at 0x41036B: pkcs15_add_object (framework-pkcs15.c:679)
==20626==    by 0x410B27: pkcs15_gen_keypair (framework-pkcs15.c:1761)
==20626==    by 0x40980D: C_GenerateKeyPair (pkcs11-object.c:869)
==20626==    by 0x4078CD: main (pkcs11_1.c:71)
==20626==  Address 0x632d3e0 is 0 bytes inside a block of size 584 free'd
==20626==    at 0x4C24A28: free (vg_replace_malloc.c:325)
==20626==    by 0x4E5452B: sc_pkcs15init_delete_object (pkcs15-lib.c:2903)
==20626==    by 0x41243B: pkcs15_dobj_destroy (framework-pkcs15.c:2721)
==20626==    by 0x40AD91: C_DestroyObject (pkcs11-object.c:96)
==20626==    by 0x407871: main (pkcs11_1.c:68)
==20626== 
==20626== 80 bytes in 1 blocks are definitely lost in loss record 76 of 148
==20626==    at 0x4C24137: calloc (vg_replace_malloc.c:418)
==20626==    by 0x40E383: __pkcs15_create_object (framework-pkcs15.c:250)
==20626==    by 0x40E45C: __pkcs15_create_data_object (framework-pkcs15.c:439)
==20626==    by 0x41164C: pkcs15_create_data (framework-pkcs15.c:1441)
==20626==    by 0x411760: pkcs15_create_object (framework-pkcs15.c:1490)
==20626==    by 0x409A35: C_CreateObject (pkcs11-object.c:53)
==20626==    by 0x40783A: main (pkcs11_1.c:65)
==20626== 
==20626== LEAK SUMMARY:
==20626==    definitely lost: 80 bytes in 1 blocks



git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3799 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
s 2009-11-01 13:55:52 +00:00
parent 3a5db68158
commit f8c6e28bac
1 changed files with 25 additions and 0 deletions

View File

@ -273,6 +273,24 @@ __pkcs15_release_object(struct pkcs15_any_object *obj)
return 0;
}
static int
__pkcs15_delete_object(struct pkcs15_fw_data *fw_data, struct pkcs15_any_object *obj)
{
unsigned int i;
if (fw_data->num_objects == 0)
return SC_ERROR_INTERNAL;
for (i = 0; i < fw_data->num_objects; ++i)
if (fw_data->objects[i] == obj) {
fw_data->objects[i] = fw_data->objects[--fw_data->num_objects];
if (__pkcs15_release_object(obj) > 0)
return SC_ERROR_INTERNAL;
return SC_SUCCESS;
}
return SC_ERROR_OBJECT_NOT_FOUND;
}
static int public_key_created(struct pkcs15_fw_data *fw_data,
const unsigned int num_objects,
const u8 *id,
@ -2726,6 +2744,13 @@ static CK_RV pkcs15_dobj_destroy(struct sc_pkcs11_session *session, void *object
if (rv == 0)
rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object);
}
if (rv >= 0) {
/* pool_find_and_delete is called, therefore correct refcont
* Oppose to pkcs15_add_object */
--((struct pkcs15_any_object*)object)->refcount;
/* Delete object in pkcs15 */
rv = __pkcs15_delete_object(fw_data, (struct pkcs15_any_object*)object);
}
sc_pkcs15init_unbind(profile);
sc_unlock(card->card);