From d2907f03810f07a684abfe67e0cb2be81325029d Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Mon, 9 Mar 2015 08:27:18 +1300 Subject: [PATCH] Bug 1140797 - Prevent fatal assert when doing base64 decode in gmp-clearkey. r=edwin --- media/gmp-clearkey/0.1/ClearKeyUtils.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/media/gmp-clearkey/0.1/ClearKeyUtils.cpp b/media/gmp-clearkey/0.1/ClearKeyUtils.cpp index 280b313a00b3..f7b77e43860b 100644 --- a/media/gmp-clearkey/0.1/ClearKeyUtils.cpp +++ b/media/gmp-clearkey/0.1/ClearKeyUtils.cpp @@ -395,24 +395,29 @@ Decode6Bit(string& aStr) } static bool -DecodeBase64(string& aEncoded, vector& aOutDecoded) +DecodeBase64KeyOrId(string& aEncoded, vector& aOutDecoded) { - if (!Decode6Bit(aEncoded)) { + if (aEncoded.size() != 22 || // Can't decode to 16 byte CENC key or keyId. + !Decode6Bit(aEncoded)) { return false; } // The number of bytes we haven't yet filled in the current byte, mod 8. int shift = 0; - aOutDecoded.resize(aEncoded.length() * 6 / 8); - aOutDecoded.reserve(aEncoded.length() * 6 / 8 + 1); - auto out = aOutDecoded.begin(); + aOutDecoded.resize(16); + vector::iterator out = aOutDecoded.begin(); for (size_t i = 0; i < aEncoded.length(); i++) { if (!shift) { *out = aEncoded[i] << 2; } else { *out |= aEncoded[i] >> (6 - shift); - *(++out) = aEncoded[i] << (shift + 2); + out++; + if (out == aOutDecoded.end()) { + // Hit last 6bit octed in encoded, which is padding and can be ignored. + break; + } + *out = aEncoded[i] << (shift + 2); } shift = (shift + 2) % 8; } @@ -423,7 +428,8 @@ DecodeBase64(string& aEncoded, vector& aOutDecoded) static bool DecodeKey(string& aEncoded, Key& aOutDecoded) { - return DecodeBase64(aEncoded, aOutDecoded) && + return + DecodeBase64KeyOrId(aEncoded, aOutDecoded) && // Key should be 128 bits long. aOutDecoded.size() == CLEARKEY_KEY_LEN; } @@ -477,7 +483,7 @@ ParseKeyObject(ParserContext& aCtx, KeyIdPair& aOutKey) return !key.empty() && !keyId.empty() && - DecodeBase64(keyId, aOutKey.mKeyId) && + DecodeBase64KeyOrId(keyId, aOutKey.mKeyId) && DecodeKey(key, aOutKey.mKey) && GetNextSymbol(aCtx) == '}'; }