SHA256
1
0
forked from pool/openssl
openssl/0022-bignum-allow-concurrent-BN_MONT_CTX_set_locked.patch
Stephan Kulow 6a3418284a Accepting request 233553 from Base:System
- 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
2014-05-14 08:26:07 +00:00

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