Bug 431929: Release the lock before returning. Acquire the lock after
null checks. r=nelson.
--- a/security/nss/lib/base/arena.c
+++ b/security/nss/lib/base/arena.c
@@ -524,16 +524,17 @@ nssArena_Destroy
/* Just got destroyed */
nss_SetError(NSS_ERROR_INVALID_ARENA);
return PR_FAILURE;
}
PR_Lock(arena->lock);
#ifdef DEBUG
if( PR_SUCCESS != arena_remove_pointer(arena) ) {
+ PR_Unlock(arena->lock);
return PR_FAILURE;
}
#endif /* DEBUG */
#ifdef ARENA_DESTRUCTOR_LIST
/* Note that the arena is locked at this time */
nss_arena_call_destructor_chain(arena->first_destructor);
#endif /* ARENA_DESTRUCTOR_LIST */
@@ -976,22 +977,22 @@ nss_ZFreeIf
} else {
/* Arena */
#ifdef NSSDEBUG
if( PR_SUCCESS != nssArena_verifyPointer(h->arena) ) {
return PR_FAILURE;
}
#endif /* NSSDEBUG */
- PR_Lock(h->arena->lock);
if( (PRLock *)NULL == h->arena->lock ) {
/* Just got destroyed.. so this pointer is invalid */
nss_SetError(NSS_ERROR_INVALID_POINTER);
return PR_FAILURE;
}
+ PR_Lock(h->arena->lock);
(void)nsslibc_memset(pointer, 0, h->size);
/* No way to "free" it within an NSPR arena. */
PR_Unlock(h->arena->lock);
return PR_SUCCESS;
}
@@ -1079,22 +1080,22 @@ nss_ZRealloc
void *p;
/* Arena */
#ifdef NSSDEBUG
if( PR_SUCCESS != nssArena_verifyPointer(h->arena) ) {
return (void *)NULL;
}
#endif /* NSSDEBUG */
- PR_Lock(h->arena->lock);
if( (PRLock *)NULL == h->arena->lock ) {
/* Just got destroyed.. so this pointer is invalid */
nss_SetError(NSS_ERROR_INVALID_POINTER);
return (void *)NULL;
}
+ PR_Lock(h->arena->lock);
#ifdef ARENA_THREADMARK
if( (PRThread *)NULL != h->arena->marking_thread ) {
if( PR_GetCurrentThread() != h->arena->marking_thread ) {
PR_Unlock(h->arena->lock);
nss_SetError(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD);
return (void *)NULL;
}