Bug 706049 - Sanity check PrefixSet on probing, detect errors on load. r=dcamp
authorGian-Carlo Pascutto <gpascutto@mozilla.com>
Fri, 02 Dec 2011 10:46:58 +0100
changeset 82797 cddc8b0ba0b64339f82d4eb39bfaa6776389850b
parent 82796 636ea2bf3366ecabe3832080e4fb5e7e75f49306
child 82798 4be41994deb70f69eee8d14ab85819ae60f9e721
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdcamp
bugs706049
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 706049 - Sanity check PrefixSet on probing, detect errors on load. r=dcamp
toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
--- a/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
@@ -307,18 +307,25 @@ nsUrlClassifierPrefixSet::Contains(PRUin
   PRUint32 i = BinSearch(0, mIndexPrefixes.Length() - 1, target);
   if (mIndexPrefixes[i] > target && i > 0) {
     i--;
   }
 
   // Now search through the deltas for the target.
   PRUint32 diff = target - mIndexPrefixes[i];
   PRUint32 deltaIndex = mIndexStarts[i];
+  PRUint32 deltaSize  = mDeltas.Length();
   PRUint32 end = (i + 1 < mIndexStarts.Length()) ? mIndexStarts[i+1]
-                                                 : mDeltas.Length();
+                                                 : deltaSize;
+
+  // Sanity check the read values
+  if (end > deltaSize) {
+    return NS_ERROR_FILE_CORRUPTED;
+  }
+
   while (diff > 0 && deltaIndex < end) {
     diff -= mDeltas[deltaIndex];
     deltaIndex++;
   }
 
   if (diff == 0) {
     *aFound = true;
   }
@@ -397,49 +404,55 @@ nsUrlClassifierPrefixSet::Probe(PRUint32
 
 nsresult
 nsUrlClassifierPrefixSet::LoadFromFd(AutoFDClose & fileFd)
 {
   PRUint32 magic;
   PRInt32 read;
 
   read = PR_Read(fileFd, &magic, sizeof(PRUint32));
-  NS_ENSURE_TRUE(read > 0, NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(read == sizeof(PRUint32), NS_ERROR_FAILURE);
 
   if (magic == PREFIXSET_VERSION_MAGIC) {
     PRUint32 indexSize;
     PRUint32 deltaSize;
 
     read = PR_Read(fileFd, &mRandomKey, sizeof(PRUint32));
-    NS_ENSURE_TRUE(read > 0, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(read == sizeof(PRUint32), NS_ERROR_FILE_CORRUPTED);
     read = PR_Read(fileFd, &indexSize, sizeof(PRUint32));
-    NS_ENSURE_TRUE(read > 0, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(read == sizeof(PRUint32), NS_ERROR_FILE_CORRUPTED);
     read = PR_Read(fileFd, &deltaSize, sizeof(PRUint32));
-    NS_ENSURE_TRUE(read > 0, NS_ERROR_FAILURE);
+    NS_ENSURE_TRUE(read == sizeof(PRUint32), NS_ERROR_FILE_CORRUPTED);
 
     if (indexSize == 0) {
       LOG(("stored PrefixSet is empty!"));
       return NS_ERROR_FAILURE;
     }
 
+    if (deltaSize > (indexSize * DELTAS_LIMIT)) {
+      return NS_ERROR_FILE_CORRUPTED;
+    }
+
     nsTArray<PRUint32> mNewIndexPrefixes;
     nsTArray<PRUint32> mNewIndexStarts;
     nsTArray<PRUint16> mNewDeltas;
 
     mNewIndexStarts.SetLength(indexSize);
     mNewIndexPrefixes.SetLength(indexSize);
     mNewDeltas.SetLength(deltaSize);
 
-    read = PR_Read(fileFd, mNewIndexPrefixes.Elements(), indexSize*sizeof(PRUint32));
-    NS_ENSURE_TRUE(read > 0, NS_ERROR_FAILURE);
-    read = PR_Read(fileFd, mNewIndexStarts.Elements(), indexSize*sizeof(PRUint32));
-    NS_ENSURE_TRUE(read > 0, NS_ERROR_FAILURE);
+    PRInt32 toRead = indexSize*sizeof(PRUint32);
+    read = PR_Read(fileFd, mNewIndexPrefixes.Elements(), toRead);
+    NS_ENSURE_TRUE(read == toRead, NS_ERROR_FILE_CORRUPTED);
+    read = PR_Read(fileFd, mNewIndexStarts.Elements(), toRead);
+    NS_ENSURE_TRUE(read == toRead, NS_ERROR_FILE_CORRUPTED);
     if (deltaSize > 0) {
-      read = PR_Read(fileFd, mNewDeltas.Elements(), deltaSize*sizeof(PRUint16));
-      NS_ENSURE_TRUE(read > 0, NS_ERROR_FAILURE);
+      toRead = deltaSize*sizeof(PRUint16);
+      read = PR_Read(fileFd, mNewDeltas.Elements(), toRead);
+      NS_ENSURE_TRUE(read == toRead, NS_ERROR_FILE_CORRUPTED);
     }
 
     MutexAutoLock lock(mPrefixSetLock);
 
     mIndexPrefixes.SwapElements(mNewIndexPrefixes);
     mIndexStarts.SwapElements(mNewIndexStarts);
     mDeltas.SwapElements(mNewDeltas);