Bug 347106: Need function to clear out PLArenas in PLArenaPools for security
authornelson%bolyard.com
Sun, 28 Mar 2010 20:46:36 +0000
changeset 4223 f72f74b7c75f1fe22d67e911bc27617b8717d522
parent 4222 6c0cfd1950ced9b24997c2c864e016ce9ba0fc52
child 4224 e7a80187422a82685bec9d054e8880e337db86ea
push idunknown
push userunknown
push dateunknown
bugs347106
Bug 347106: Need function to clear out PLArenas in PLArenaPools for security Patch contributed by Nelson Bolyard <nelson@bolyard.me>, r=wtc
lib/ds/plarena.c
lib/ds/plarena.h
lib/ds/plarenas.h
lib/ds/plds.def
--- a/lib/ds/plarena.c
+++ b/lib/ds/plarena.c
@@ -251,36 +251,46 @@ PR_IMPLEMENT(void *) PL_ArenaGrow(
     void *newp;
 
     PL_ARENA_ALLOCATE(newp, pool, size + incr);
     if (newp)
         memcpy(newp, p, size);
     return newp;
 }
 
+static void ClearArenaList(PLArena *a, PRInt32 pattern)
+{
+
+    for (; a; a = a->next) {
+        PR_ASSERT(a->base <= a->avail && a->avail <= a->limit);
+        a->avail = a->base;
+	PL_CLEAR_UNUSED_PATTERN(a, pattern);
+    }
+}
+
+PR_IMPLEMENT(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern)
+{
+    ClearArenaList(pool->first.next, pattern);
+}
+
 /*
  * Free tail arenas linked after head, which may not be the true list head.
  * Reset pool->current to point to head in case it pointed at a tail arena.
  */
 static void FreeArenaList(PLArenaPool *pool, PLArena *head, PRBool reallyFree)
 {
     PLArena **ap, *a;
 
     ap = &head->next;
     a = *ap;
     if (!a)
         return;
 
 #ifdef DEBUG
-    do {
-        PR_ASSERT(a->base <= a->avail && a->avail <= a->limit);
-        a->avail = a->base;
-        PL_CLEAR_UNUSED(a);
-    } while ((a = a->next) != 0);
-    a = *ap;
+    ClearArenaList(a, PL_FREE_PATTERN);
 #endif
 
     if (reallyFree) {
         do {
             *ap = a->next;
             PL_CLEAR_ARENA(a);
             PL_COUNT_ARENA(pool,--);
             PR_DELETE(a);
--- a/lib/ds/plarena.h
+++ b/lib/ds/plarena.h
@@ -133,21 +133,22 @@ struct PLArenaPool {
             p = PL_ArenaGrow(pool, p, size, incr); \
         } \
         PL_ArenaCountGrowth(pool, size, incr); \
     PR_END_MACRO
 
 #define PL_ARENA_MARK(pool) ((void *) (pool)->current->avail)
 #define PR_UPTRDIFF(p,q) ((PRUword)(p) - (PRUword)(q))
 
+#define PL_CLEAR_UNUSED_PATTERN(a, pattern) \
+	   (PR_ASSERT((a)->avail <= (a)->limit), \
+	   memset((void*)(a)->avail, (pattern), (a)->limit - (a)->avail))
 #ifdef DEBUG
 #define PL_FREE_PATTERN 0xDA
-#define PL_CLEAR_UNUSED(a) (PR_ASSERT((a)->avail <= (a)->limit), \
-                           memset((void*)(a)->avail, PL_FREE_PATTERN, \
-                           (a)->limit - (a)->avail))
+#define PL_CLEAR_UNUSED(a) PL_CLEAR_UNUSED_PATTERN((a), PL_FREE_PATTERN)
 #define PL_CLEAR_ARENA(a)  memset((void*)(a), PL_FREE_PATTERN, \
                            (a)->limit - (PRUword)(a))
 #else
 #define PL_CLEAR_UNUSED(a)
 #define PL_CLEAR_ARENA(a)
 #endif
 
 #define PL_ARENA_RELEASE(pool, mark) \
--- a/lib/ds/plarenas.h
+++ b/lib/ds/plarenas.h
@@ -103,13 +103,18 @@ PR_EXTERN(void) PL_CompactArenaPool(PLAr
 **/
 PR_EXTERN(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb);
 
 PR_EXTERN(void *) PL_ArenaGrow(
     PLArenaPool *pool, void *p, PRUint32 size, PRUint32 incr);
 
 PR_EXTERN(void) PL_ArenaRelease(PLArenaPool *pool, char *mark);
 
+/*
+** memset contents of all arenas in pool to pattern
+*/
+PR_EXTERN(void) PL_ClearArenaPool(PLArenaPool *pool, PRInt32 pattern);
+
 PR_END_EXTERN_C
 
 #endif /* defined(PLARENAS_H) */
 
 /* plarenas */
--- a/lib/ds/plds.def
+++ b/lib/ds/plds.def
@@ -76,8 +76,13 @@ libVersionPoint;
 ;+    local: *;
 ;+};
 ;+
 ;+NSPR_4.1 {
 ;+    global:
 PL_HashTableLookupConst;
 PL_HashTableRawLookupConst;
 ;+} NSPR_4.0;
+;+
+;+NSPR_4.8.5 {
+;+    global:
+PL_ClearArenaPool;
+;+} NSPR_4.1;