#540: M1510114 M1502871 M1494364 M1485864

This commit is contained in:
Cameron Kaiser 2019-01-10 00:47:37 -08:00
parent 424b846d29
commit 2dba79e825
7 changed files with 133 additions and 91 deletions

View File

@ -2967,6 +2967,8 @@ BackgroundCursorChild::RecvResponse(const CursorResponse& aResponse)
RefPtr<IDBCursor> cursor;
mStrongCursor.swap(cursor);
RefPtr<IDBTransaction> transaction = mTransaction;
switch (aResponse.type()) {
case CursorResponse::Tnsresult:
HandleResponse(aResponse.get_nsresult());
@ -2996,7 +2998,7 @@ BackgroundCursorChild::RecvResponse(const CursorResponse& aResponse)
MOZ_CRASH("Should never get here!");
}
mTransaction->OnRequestFinished(/* aActorDestroyedNormally */ true);
transaction->OnRequestFinished(/* aActorDestroyedNormally */ true);
return true;
}

View File

@ -2039,21 +2039,21 @@ nsProtocolProxyService::PruneProxyInfo(const nsProtocolInfo &info,
return;
}
// Now, scan to see if all remaining proxies are disabled. If so, then
// Scan to see if all remaining non-direct proxies are disabled. If so, then
// we'll just bail and return them all. Otherwise, we'll go and prune the
// disabled ones.
bool allDisabled = true;
bool allNonDirectProxiesDisabled = true;
nsProxyInfo *iter;
for (iter = head; iter; iter = iter->mNext) {
if (!IsProxyDisabled(iter)) {
allDisabled = false;
if (!IsProxyDisabled(iter) && iter->mType != kProxyType_DIRECT) {
allNonDirectProxiesDisabled = false;
break;
}
}
if (allDisabled)
if (allNonDirectProxiesDisabled)
LOG(("All proxies are disabled, so trying all again"));
else {
// remove any disabled proxies.

View File

@ -356,6 +356,12 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
nsCOMPtr<nsISupports> parserKungFuDeathGrip(mParser);
mozilla::Unused << parserKungFuDeathGrip;
RefPtr<nsHtml5StreamParser> streamParserGrip;
if (mParser) {
streamParserGrip = GetParser()->GetStreamParser();
}
mozilla::Unused
<< streamParserGrip; // Intentionally not used within function
// Remember the entry time
(void) nsContentSink::WillParseImpl();
@ -414,11 +420,6 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
mOpQueue.Clear(); // clear in order to be able to assert in destructor
return;
}
// Not sure if this grip is still needed, but previously, the code
// gripped before calling ParseUntilBlocked();
RefPtr<nsHtml5StreamParser> streamKungFuDeathGrip =
GetParser()->GetStreamParser();
mozilla::Unused << streamKungFuDeathGrip;
// Now parse content left in the document.write() buffer queue if any.
// This may generate tree ops on its own or dequeue a speculation.
nsresult rv = GetParser()->ParseUntilBlocked();

View File

@ -4788,38 +4788,61 @@ mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
/* }}} */
/* {{{ mp_to_fixlen_octets(mp, str) */
/* output a buffer of big endian octets exactly as long as requested. */
/* output a buffer of big endian octets exactly as long as requested.
constant time on the value of mp. */
mp_err
mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
{
int ix, pos = 0;
unsigned int bytes;
int ix, jx;
unsigned int bytes;
ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
ARGCHK(mp != NULL, MP_BADARG);
ARGCHK(str != NULL, MP_BADARG);
ARGCHK(!SIGN(mp), MP_BADARG);
ARGCHK(length > 0, MP_BADARG);
bytes = mp_unsigned_octet_size(mp);
ARGCHK(bytes <= length, MP_BADARG);
/* Constant time on the value of mp. Don't use mp_unsigned_octet_size. */
bytes = USED(mp) * MP_DIGIT_SIZE;
/* place any needed leading zeros */
for (;length > bytes; --length) {
*str++ = 0;
/* If the output is shorter than the native size of mp, then check that any
* bytes not written have zero values. This check isn't constant time on
* the assumption that timing-sensitive callers can guarantee that mp fits
* in the allocated space. */
ix = USED(mp) - 1;
if (bytes > length) {
unsigned int zeros = bytes - length;
while (zeros >= MP_DIGIT_SIZE) {
ARGCHK(DIGIT(mp, ix) == 0, MP_BADARG);
zeros -= MP_DIGIT_SIZE;
ix--;
}
if (zeros > 0) {
mp_digit d = DIGIT(mp, ix);
mp_digit m = ~0ULL << ((MP_DIGIT_SIZE - zeros) * CHAR_BIT);
ARGCHK((d & m) == 0, MP_BADARG);
for (jx = MP_DIGIT_SIZE - zeros - 1; jx >= 0; jx--) {
*str++ = d >> (jx * CHAR_BIT);
}
ix--;
}
} else if (bytes < length) {
/* Place any needed leading zeros. */
unsigned int zeros = length - bytes;
memset(str, 0, zeros);
str += zeros;
}
/* Iterate over each digit... */
for(ix = USED(mp) - 1; ix >= 0; ix--) {
mp_digit d = DIGIT(mp, ix);
int jx;
/* Iterate over each whole digit... */
for (; ix >= 0; ix--) {
mp_digit d = DIGIT(mp, ix);
/* Unpack digit bytes, high order first */
for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
if (!pos && !x) /* suppress leading zeros */
continue;
str[pos++] = x;
for (jx = MP_DIGIT_SIZE - 1; jx >= 0; jx--) {
*str++ = d >> (jx * CHAR_BIT);
}
}
if (!pos)
str[pos++] = 0;
return MP_OKAY;
} /* end mp_to_fixlen_octets() */
/* }}} */

View File

@ -125,7 +125,8 @@ typedef int mp_sword;
#define MP_WORD_MAX UINT_MAX
#endif
#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))
#define MP_DIGIT_SIZE sizeof(mp_digit)
#define MP_DIGIT_BIT (CHAR_BIT * MP_DIGIT_SIZE)
#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))
#define MP_RADIX (1+(mp_word)MP_DIGIT_MAX)

View File

@ -907,48 +907,56 @@ RSA_DecryptBlock(RSAPrivateKey * key,
const unsigned char * input,
unsigned int inputLen)
{
SECStatus rv;
PRInt8 rv;
unsigned int modulusLen = rsa_modulusLen(&key->modulus);
unsigned int i;
unsigned char * buffer;
unsigned char *buffer = NULL;
unsigned int outLen = 0;
unsigned int copyOutLen = modulusLen - 11;
if (inputLen != modulusLen)
goto failure;
buffer = (unsigned char *)PORT_Alloc(modulusLen + 1);
if (!buffer)
goto failure;
rv = RSA_PrivateKeyOp(key, buffer, input);
if (rv != SECSuccess)
goto loser;
/* XXX(rsleevi): Constant time */
if (buffer[0] != RSA_BLOCK_FIRST_OCTET ||
buffer[1] != (unsigned char)RSA_BlockPublic) {
goto loser;
if (inputLen != modulusLen || modulusLen < 10) {
return SECFailure;
}
*outputLen = 0;
for (i = 2; i < modulusLen; i++) {
if (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
*outputLen = modulusLen - i - 1;
break;
}
}
if (*outputLen == 0)
goto loser;
if (*outputLen > maxOutputLen)
goto loser;
PORT_Memcpy(output, buffer + modulusLen - *outputLen, *outputLen);
if (copyOutLen > maxOutputLen) {
copyOutLen = maxOutputLen;
}
// Allocate enough space to decrypt + copyOutLen to allow copying outLen later.
buffer = PORT_ZAlloc(modulusLen + 1 + copyOutLen);
if (!buffer) {
return SECFailure;
}
// rv is 0 if everything is going well and 1 if an error occurs.
rv = RSA_PrivateKeyOp(key, buffer, input) != SECSuccess;
rv |= (buffer[0] != RSA_BLOCK_FIRST_OCTET) |
(buffer[1] != (unsigned char)RSA_BlockPublic);
// There have to be at least 8 bytes of padding.
for (i = 2; i < 10; i++) {
rv |= buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET;
}
for (i = 10; i < modulusLen; i++) {
unsigned int newLen = modulusLen - i - 1;
unsigned int c = (buffer[i] == RSA_BLOCK_AFTER_PAD_OCTET) & (outLen == 0);
outLen = constantTimeCondition(c, newLen, outLen);
}
rv |= outLen == 0;
rv |= outLen > maxOutputLen;
// Note that output is set even if SECFailure is returned.
PORT_Memcpy(output, buffer + modulusLen - outLen, copyOutLen);
*outputLen = constantTimeCondition(outLen > maxOutputLen, maxOutputLen,
outLen);
PORT_Free(buffer);
return SECSuccess;
loser:
PORT_Free(buffer);
failure:
return SECFailure;
for (i = 1; i < sizeof(rv) * 8; i <<= 1) {
rv |= rv << i;
}
return (SECStatus)rv;
}
/*

View File

@ -9760,6 +9760,23 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
return pms;
}
static void
ssl3_CSwapPK11SymKey(PK11SymKey **x, PK11SymKey **y, PRBool c)
{
uintptr_t mask = (uintptr_t)c;
unsigned int i;
for (i = 1; i < sizeof(uintptr_t) * 8; i <<= 1) {
mask |= mask << i;
}
uintptr_t x_ptr = (uintptr_t)*x;
uintptr_t y_ptr = (uintptr_t)*y;
uintptr_t tmp = (x_ptr ^ y_ptr) & mask;
x_ptr = x_ptr ^ tmp;
y_ptr = y_ptr ^ tmp;
*x = (PK11SymKey *)x_ptr;
*y = (PK11SymKey *)y_ptr;
}
/* Note: The Bleichenbacher attack on PKCS#1 necessitates that we NEVER
* return any indication of failure of the Client Key Exchange message,
* where that failure is caused by the content of the client's message.
@ -9868,13 +9885,9 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
} else
#endif
{
PK11SymKey *tmpPms[2] = {NULL, NULL};
PK11SlotInfo *slot;
int useFauxPms = 0;
#define currentPms tmpPms[!useFauxPms]
#define unusedPms tmpPms[useFauxPms]
#define realPms tmpPms[1]
#define fauxPms tmpPms[0]
PK11SymKey *pms = NULL;
PK11SymKey *fauxPms = NULL;
PK11SlotInfo *slot = NULL;
#ifndef NO_PKCS11_BYPASS
double_bypass:
@ -9934,29 +9947,28 @@ double_bypass:
* the unwrap. Rather, it is the mechanism with which the
* unwrapped pms will be used.
*/
realPms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
pms = PK11_PubUnwrapSymKey(serverKey, &enc_pms,
CKM_SSL3_MASTER_KEY_DERIVE, CKA_DERIVE, 0);
/* Temporarily use the PMS if unwrapping the real PMS fails. */
useFauxPms |= (realPms == NULL);
ssl3_CSwapPK11SymKey(&pms, &fauxPms, pms == NULL);
/* Attempt to derive the MS from the PMS. This is the only way to
* check the version field in the RSA PMS. If this fails, we
* then use the faux PMS in place of the PMS. Note that this
* operation should never fail if we are using the faux PMS
* since it is correctly formatted. */
rv = ssl3_ComputeMasterSecret(ss, currentPms, NULL);
/* If we succeeded, then select the true PMS and discard the
* FPMS. Else, select the FPMS and select the true PMS */
useFauxPms |= (rv != SECSuccess);
if (unusedPms) {
PK11_FreeSymKey(unusedPms);
}
rv = ssl3_ComputeMasterSecret(ss, pms, NULL);
/* If we succeeded, then select the true PMS, else select the FPMS. */
ssl3_CSwapPK11SymKey(&pms, &fauxPms, (rv != SECSuccess) & (fauxPms != NULL));
/* This step will derive the MS from the PMS, among other things. */
rv = ssl3_InitPendingCipherSpec(ss, currentPms);
PK11_FreeSymKey(currentPms);
rv = ssl3_InitPendingCipherSpec(ss, pms);
/* Clear both PMS. */
PK11_FreeSymKey(pms);
PK11_FreeSymKey(fauxPms);
}
if (rv != SECSuccess) {
@ -9964,11 +9976,6 @@ double_bypass:
return SECFailure; /* error code set by ssl3_InitPendingCipherSpec */
}
#undef currentPms
#undef unusedPms
#undef realPms
#undef fauxPms
return SECSuccess;
}