Fix for 134095 - allow PKCS#11 framework to free attributes for non-const token objects

This commit is contained in:
jpierre%netscape.com 2002-03-29 07:34:22 +00:00
parent 70ec79e458
commit b38e1cb19d
3 changed files with 64 additions and 18 deletions

View File

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: bobject.c,v $ $Revision: 1.1 $ $Date: 2002/02/08 00:10:03 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: bobject.c,v $ $Revision: 1.2 $ $Date: 2002/03/29 07:34:22 $ $Name: $";
#endif /* DEBUG */
#include "builtins.h"
@ -163,7 +163,7 @@ builtins_mdObject_GetAttributeSize
return 0;
}
static const NSSItem *
static NSSCKFWItem
builtins_mdObject_GetAttribute
(
NSSCKMDObject *mdObject,
@ -178,17 +178,22 @@ builtins_mdObject_GetAttribute
CK_RV *pError
)
{
NSSCKFWItem mdItem;
builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
CK_ULONG i;
mdItem.needsFreeing = PR_FALSE;
mdItem.item = (NSSItem*) NULL;
for( i = 0; i < io->n; i++ ) {
if( attribute == io->types[i] ) {
return &io->items[i];
mdItem.item = (NSSItem*) &io->items[i];
return mdItem;
}
}
*pError = CKR_ATTRIBUTE_TYPE_INVALID;
return (NSSItem *)NULL;
return mdItem;
}
static CK_ULONG
@ -226,6 +231,7 @@ builtins_prototype_mdObject = {
builtins_mdObject_GetAttributeTypes,
builtins_mdObject_GetAttributeSize,
builtins_mdObject_GetAttribute,
NULL, /* FreeAttribute */
NULL, /* SetAttribute */
builtins_mdObject_GetObjectSize,
(void *)NULL /* null terminator */

View File

@ -35,7 +35,7 @@
#define NSSCKMDT_H
#ifdef DEBUG
static const char NSSCKMDT_CVS_ID[] = "@(#) $RCSfile: nssckmdt.h,v $ $Revision: 1.2 $ $Date: 2001/01/05 01:38:04 $ $Name: $";
static const char NSSCKMDT_CVS_ID[] = "@(#) $RCSfile: nssckmdt.h,v $ $Revision: 1.3 $ $Date: 2002/03/29 07:34:20 $ $Name: $";
#endif /* DEBUG */
/*
@ -65,6 +65,21 @@ typedef struct NSSCKMDFindObjectsStr NSSCKMDFindObjects;
typedef struct NSSCKMDMechanismStr NSSCKMDMechanism;
typedef struct NSSCKMDObjectStr NSSCKMDObject;
/*
* NSSCKFWItem
*
* This is a structure used by modules to return object attributes.
* The needsFreeing bit indicates whether the object needs to be freed.
* If so, the framework will call the FreeAttribute function on the item
* after it is done using it.
*
*/
typedef struct {
PRBool needsFreeing;
NSSItem* item;
} NSSCKFWItem ;
/*
* NSSCKMDInstance
*
@ -1943,13 +1958,13 @@ struct NSSCKMDObjectStr {
);
/*
* This routine returns the specified attribute. It can return
* NULL upon error. The pointer in the item will not be freed;
* any host memory required should come from the object's arena
* (which is likely the Framework's token or session arena).
* It may return NULL on error.
* This routine returns an NSSCKFWItem structure.
* The item pointer points to an NSSItem containing the attribute value.
* The needsFreeing bit tells the framework whether to call the
* FreeAttribute function . Upon error, an NSSCKFWItem structure
* with a NULL NSSItem item pointer will be returned
*/
const NSSItem *(PR_CALLBACK *GetAttribute)(
NSSCKFWItem (PR_CALLBACK *GetAttribute)(
NSSCKMDObject *mdObject,
NSSCKFWObject *fwObject,
NSSCKMDSession *mdSession,
@ -1962,6 +1977,13 @@ struct NSSCKMDObjectStr {
CK_RV *pError
);
/*
* This routine returns CKR_OK if the attribute could be freed.
*/
CK_RV (PR_CALLBACK *FreeAttribute)(
NSSCKFWItem * item
);
/*
* This routine changes the specified attribute. If unimplemented,
* the object will be considered read-only.

View File

@ -32,7 +32,7 @@
*/
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: object.c,v $ $Revision: 1.7 $ $Date: 2001/11/16 19:41:49 $ $Name: $";
static const char CVS_ID[] = "@(#) $RCSfile: object.c,v $ $Revision: 1.8 $ $Date: 2002/03/29 07:34:20 $ $Name: $";
#endif /* DEBUG */
/*
@ -598,7 +598,7 @@ nssCKFWObject_GetAttribute
)
{
NSSItem *rv = (NSSItem *)NULL;
const NSSItem *mdItem;
NSSCKFWItem mdItem;
#ifdef NSSDEBUG
if( (CK_RV *)NULL == pError ) {
@ -626,7 +626,7 @@ nssCKFWObject_GetAttribute
fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
attribute, pError);
if( (NSSItem *)NULL == mdItem ) {
if( (NSSItem *)NULL == mdItem.item ) {
if( CKR_OK == *pError ) {
*pError = CKR_GENERAL_ERROR;
}
@ -645,7 +645,7 @@ nssCKFWObject_GetAttribute
}
if( (void *)NULL == rv->data ) {
rv->size = mdItem->size;
rv->size = mdItem.item->size;
rv->data = nss_ZAlloc(arenaOpt, rv->size);
if( (void *)NULL == rv->data ) {
*pError = CKR_HOST_MEMORY;
@ -656,8 +656,8 @@ nssCKFWObject_GetAttribute
goto done;
}
} else {
if( rv->size >= mdItem->size ) {
rv->size = mdItem->size;
if( rv->size >= mdItem.item->size ) {
rv->size = mdItem.item->size;
} else {
*pError = CKR_BUFFER_TOO_SMALL;
/* Should we set rv->size to mdItem->size? */
@ -667,7 +667,25 @@ nssCKFWObject_GetAttribute
}
}
(void)nsslibc_memcpy(rv->data, mdItem->data, rv->size);
(void)nsslibc_memcpy(rv->data, mdItem.item->data, rv->size);
if (PR_TRUE == mdItem.needsFreeing) {
PR_ASSERT(fwObject->mdObject->FreeAttribute);
if (fwObject->mdObject->FreeAttribute) {
*pError = fwObject->mdObject->FreeAttribute(&mdItem);
} else {
/* bad, bad module : it allocated an attribute
but does not know how to free it. a memory leak will result
There is no way to prevent the leak, though . But report an
error so it doesn't go unnoticed on opt builds. On dbg we
assert above for the FreeAttribute function */
if (rv) {
nss_ZFreeIf(rv);
}
*pError = CKR_HOST_MEMORY;
}
}
done:
(void)nssCKFWMutex_Unlock(fwObject->mutex);