Bug 431929: Release the lock before returning. Acquire the lock after
authorwtc%google.com
Tue, 13 May 2008 01:22:35 +0000
changeset 8593 0b86f95a811519d5f1fc656bb53d7edcbeb17dbc
parent 8592 c709cdf9151b363bb0b0b43710ad3360950cf886
child 8594 0e5f81972f9821baa7a232b0ad70184a7f57e5f5
push idunknown
push userunknown
push dateunknown
bugs431929
Bug 431929: Release the lock before returning. Acquire the lock after null checks. r=nelson.
security/nss/lib/base/arena.c
--- 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;
       }