forked from pool/openssl
6a3418284a
- Add upstream patches fixing coverity scan issues: * 0018-fix-coverity-issues-966593-966596.patch * 0020-Initialize-num-properly.patch * 0022-bignum-allow-concurrent-BN_MONT_CTX_set_locked.patch * 0023-evp-prevent-underflow-in-base64-decoding.patch * 0024-Fixed-NULL-pointer-dereference-in-PKCS7_dataDecode-r.patch * 0025-fix-coverity-issue-966597-error-line-is-not-always-i.patch - Update 0001-libcrypto-Hide-library-private-symbols.patch to cover more private symbols, now 98% complete and probably not much more can be done to fix the rest of the ill-defined API. - openssl-fips-hidden.patch new, hides private symbols added by the FIPS patches. - openssl-no-egd.patch disable the EGD (entropy gathering daemon) interface, we have no EGD in the distro and obtaining entropy from a place other than /dev/*random, the hardware rng or the openSSL internal PRNG is an extremely bad & dangerous idea. - use secure_getenv instead of getenv everywhere. (forwarded request 233217 from elvigia) OBS-URL: https://build.opensuse.org/request/show/233553 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/openssl?expand=0&rev=117
86 lines
2.5 KiB
Diff
86 lines
2.5 KiB
Diff
From d8afda60a991791f27cfac79186b1f8a4f4e30a0 Mon Sep 17 00:00:00 2001
|
|
From: Geoff Thorpe <geoff@openssl.org>
|
|
Date: Sun, 4 May 2014 16:19:22 -0400
|
|
Subject: [PATCH 22/23] bignum: allow concurrent BN_MONT_CTX_set_locked()
|
|
|
|
The lazy-initialisation of BN_MONT_CTX was serialising all threads, as
|
|
noted by Daniel Sands and co at Sandia. This was to handle the case that
|
|
2 or more threads race to lazy-init the same context, but stunted all
|
|
scalability in the case where 2 or more threads are doing unrelated
|
|
things! We favour the latter case by punishing the former. The init work
|
|
gets done by each thread that finds the context to be uninitialised, and
|
|
we then lock the "set" logic after that work is done - the winning
|
|
thread's work gets used, the losing threads throw away what they've done.
|
|
|
|
Signed-off-by: Geoff Thorpe <geoff@openssl.org>
|
|
---
|
|
crypto/bn/bn_mont.c | 46 ++++++++++++++++++++++++++--------------------
|
|
1 file changed, 26 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c
|
|
index 427b5cf..ee8532c 100644
|
|
--- a/crypto/bn/bn_mont.c
|
|
+++ b/crypto/bn/bn_mont.c
|
|
@@ -478,32 +478,38 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
|
|
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
|
|
const BIGNUM *mod, BN_CTX *ctx)
|
|
{
|
|
- int got_write_lock = 0;
|
|
BN_MONT_CTX *ret;
|
|
|
|
CRYPTO_r_lock(lock);
|
|
- if (!*pmont)
|
|
+ ret = *pmont;
|
|
+ CRYPTO_r_unlock(lock);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ /* We don't want to serialise globally while doing our lazy-init math in
|
|
+ * BN_MONT_CTX_set. That punishes threads that are doing independent
|
|
+ * things. Instead, punish the case where more than one thread tries to
|
|
+ * lazy-init the same 'pmont', by having each do the lazy-init math work
|
|
+ * independently and only use the one from the thread that wins the race
|
|
+ * (the losers throw away the work they've done). */
|
|
+ ret = BN_MONT_CTX_new();
|
|
+ if (!ret)
|
|
+ return NULL;
|
|
+ if (!BN_MONT_CTX_set(ret, mod, ctx))
|
|
{
|
|
- CRYPTO_r_unlock(lock);
|
|
- CRYPTO_w_lock(lock);
|
|
- got_write_lock = 1;
|
|
+ BN_MONT_CTX_free(ret);
|
|
+ return NULL;
|
|
+ }
|
|
|
|
- if (!*pmont)
|
|
- {
|
|
- ret = BN_MONT_CTX_new();
|
|
- if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
|
|
- BN_MONT_CTX_free(ret);
|
|
- else
|
|
- *pmont = ret;
|
|
- }
|
|
+ /* The locked compare-and-set, after the local work is done. */
|
|
+ CRYPTO_w_lock(lock);
|
|
+ if (*pmont)
|
|
+ {
|
|
+ BN_MONT_CTX_free(ret);
|
|
+ ret = *pmont;
|
|
}
|
|
-
|
|
- ret = *pmont;
|
|
-
|
|
- if (got_write_lock)
|
|
- CRYPTO_w_unlock(lock);
|
|
else
|
|
- CRYPTO_r_unlock(lock);
|
|
-
|
|
+ *pmont = ret;
|
|
+ CRYPTO_w_unlock(lock);
|
|
return ret;
|
|
}
|
|
--
|
|
1.8.4.5
|
|
|