Bug 1204155 - Account for OOM in CryptoKey::SetSymKey() r=mt
authorTim Taubert <ttaubert@mozilla.com>
Mon, 14 Sep 2015 11:19:16 +0200
changeset 300982 48dfe8c77b2f6f3cf8a81ea22d47c3f095d38b35
parent 300981 c917988efd78a3f082be29d388b87fdb194f592d
child 300983 a4bf09cda682d02ef212a8c4fbc27f00898bebef
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmt
bugs1204155
milestone44.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 1204155 - Account for OOM in CryptoKey::SetSymKey() r=mt
dom/crypto/CryptoKey.cpp
dom/crypto/CryptoKey.h
dom/crypto/WebCryptoTask.cpp
--- a/dom/crypto/CryptoKey.cpp
+++ b/dom/crypto/CryptoKey.cpp
@@ -380,19 +380,23 @@ CryptoKey::AllUsagesRecognized(const Seq
   for (uint32_t i = 0; i < aUsages.Length(); ++i) {
     if (!IsRecognizedUsage(aUsages[i])) {
       return false;
     }
   }
   return true;
 }
 
-void CryptoKey::SetSymKey(const CryptoBuffer& aSymKey)
+nsresult CryptoKey::SetSymKey(const CryptoBuffer& aSymKey)
 {
-  mSymKey = aSymKey;
+  if (!mSymKey.Assign(aSymKey)) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  return NS_OK;
 }
 
 void
 CryptoKey::SetPrivateKey(SECKEYPrivateKey* aPrivateKey)
 {
   nsNSSShutDownPreventionLock locker;
   if (!aPrivateKey || isAlreadyShutDown()) {
     mPrivateKey = nullptr;
@@ -1263,18 +1267,18 @@ CryptoKey::ReadStructuredClone(JSStructu
               ReadBuffer(aReader, sym) &&
               ReadBuffer(aReader, priv) &&
               ReadBuffer(aReader, pub) &&
               mAlgorithm.ReadStructuredClone(aReader);
   if (!read) {
     return false;
   }
 
-  if (sym.Length() > 0)  {
-    mSymKey = sym;
+  if (sym.Length() > 0 && !mSymKey.Assign(sym))  {
+    return false;
   }
   if (priv.Length() > 0) {
     mPrivateKey = CryptoKey::PrivateKeyFromPkcs8(priv, locker);
   }
   if (pub.Length() > 0)  {
     mPublicKey = CryptoKey::PublicKeyFromSpki(pub, locker);
   }
 
--- a/dom/crypto/CryptoKey.h
+++ b/dom/crypto/CryptoKey.h
@@ -122,17 +122,17 @@ public:
   nsresult AddUsageIntersecting(const nsString& aUsage, uint32_t aUsageMask);
   void AddUsage(KeyUsage aUsage);
   bool HasAnyUsage();
   bool HasUsage(KeyUsage aUsage);
   bool HasUsageOtherThan(uint32_t aUsages);
   static bool IsRecognizedUsage(const nsString& aUsage);
   static bool AllUsagesRecognized(const Sequence<nsString>& aUsages);
 
-  void SetSymKey(const CryptoBuffer& aSymKey);
+  nsresult SetSymKey(const CryptoBuffer& aSymKey);
   void SetPrivateKey(SECKEYPrivateKey* aPrivateKey);
   void SetPublicKey(SECKEYPublicKey* aPublicKey);
 
   // Accessors for the keys themselves
   // Note: GetPrivateKey and GetPublicKey return copies of the internal
   // key handles, which the caller must free with SECKEY_DestroyPrivateKey
   // or SECKEY_DestroyPublicKey.
   const CryptoBuffer& GetSymKey() const;
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -1283,17 +1283,21 @@ public:
         return;
       }
       mDataIsJwk = true;
     }
   }
 
   void SetKeyData(const CryptoBuffer& aKeyData)
   {
-    mKeyData = aKeyData;
+    if (!mKeyData.Assign(aKeyData)) {
+      mEarlyRv = NS_ERROR_DOM_OPERATION_ERR;
+      return;
+    }
+
     mDataIsJwk = false;
 
     if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK)) {
       SetJwkFromKeyData();
     }
   }
 
   void SetJwkFromKeyData()
@@ -1463,17 +1467,20 @@ public:
       if (mDataIsJwk && mJwk.mUse.WasPassed() &&
           !mJwk.mUse.Value().EqualsLiteral(JWK_USE_SIG)) {
         return NS_ERROR_DOM_DATA_ERR;
       }
     } else {
       return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
     }
 
-    mKey->SetSymKey(mKeyData);
+    if (NS_FAILED(mKey->SetSymKey(mKeyData))) {
+      return NS_ERROR_DOM_OPERATION_ERR;
+    }
+
     mKey->SetType(CryptoKey::SECRET);
 
     if (mDataIsJwk && !JwkCompatible(mJwk, mKey)) {
       return NS_ERROR_DOM_DATA_ERR;
     }
 
     mEarlyComplete = true;
     return NS_OK;
@@ -2148,18 +2155,21 @@ private:
     // just refers to a buffer managed by symKey.  The assignment copies the
     // data, so mKeyData manages one copy, while symKey manages another.
     ATTEMPT_BUFFER_ASSIGN(mKeyData, PK11_GetKeyData(symKey));
     return NS_OK;
   }
 
   virtual void Resolve() override
   {
-    mKey->SetSymKey(mKeyData);
-    mResultPromise->MaybeResolve(mKey);
+    if (NS_SUCCEEDED(mKey->SetSymKey(mKeyData))) {
+      mResultPromise->MaybeResolve(mKey);
+    } else {
+      mResultPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
+    }
   }
 
   virtual void Cleanup() override
   {
     mKey = nullptr;
   }
 };