--- /dev/null
+From 34c86f4c4a7be3b3e35aa48bd18299d4c756064d Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Mon, 8 Jun 2020 16:48:43 +1000
+Subject: crypto: af_alg - fix use-after-free in af_alg_accept() due to bh_lock_sock()
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit 34c86f4c4a7be3b3e35aa48bd18299d4c756064d upstream.
+
+The locking in af_alg_release_parent is broken as the BH socket
+lock can only be taken if there is a code-path to handle the case
+where the lock is owned by process-context. Instead of adding
+such handling, we can fix this by changing the ref counts to
+atomic_t.
+
+This patch also modifies the main refcnt to include both normal
+and nokey sockets. This way we don't have to fudge the nokey
+ref count when a socket changes from nokey to normal.
+
+Credits go to Mauricio Faria de Oliveira who diagnosed this bug
+and sent a patch for it:
+
+https://lore.kernel.org/linux-crypto/20200605161657.535043-1-mfo@canonical.com/
+
+Reported-by: Brian Moyles <bmoyles@netflix.com>
+Reported-by: Mauricio Faria de Oliveira <mfo@canonical.com>
+Fixes: 37f96694cf73 ("crypto: af_alg - Use bh_lock_sock in...")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/af_alg.c | 26 +++++++++++---------------
+ crypto/algif_aead.c | 9 +++------
+ crypto/algif_hash.c | 9 +++------
+ crypto/algif_skcipher.c | 9 +++------
+ include/crypto/if_alg.h | 4 ++--
+ 5 files changed, 22 insertions(+), 35 deletions(-)
+
+--- a/crypto/af_alg.c
++++ b/crypto/af_alg.c
+@@ -133,21 +133,15 @@ EXPORT_SYMBOL_GPL(af_alg_release);
+ void af_alg_release_parent(struct sock *sk)
+ {
+ struct alg_sock *ask = alg_sk(sk);
+- unsigned int nokey = ask->nokey_refcnt;
+- bool last = nokey && !ask->refcnt;
++ unsigned int nokey = atomic_read(&ask->nokey_refcnt);
+
+ sk = ask->parent;
+ ask = alg_sk(sk);
+
+- local_bh_disable();
+- bh_lock_sock(sk);
+- ask->nokey_refcnt -= nokey;
+- if (!last)
+- last = !--ask->refcnt;
+- bh_unlock_sock(sk);
+- local_bh_enable();
++ if (nokey)
++ atomic_dec(&ask->nokey_refcnt);
+
+- if (last)
++ if (atomic_dec_and_test(&ask->refcnt))
+ sock_put(sk);
+ }
+ EXPORT_SYMBOL_GPL(af_alg_release_parent);
+@@ -192,7 +186,7 @@ static int alg_bind(struct socket *sock,
+
+ err = -EBUSY;
+ lock_sock(sk);
+- if (ask->refcnt | ask->nokey_refcnt)
++ if (atomic_read(&ask->refcnt))
+ goto unlock;
+
+ swap(ask->type, type);
+@@ -241,7 +235,7 @@ static int alg_setsockopt(struct socket
+ int err = -EBUSY;
+
+ lock_sock(sk);
+- if (ask->refcnt)
++ if (atomic_read(&ask->refcnt) != atomic_read(&ask->nokey_refcnt))
+ goto unlock;
+
+ type = ask->type;
+@@ -308,12 +302,14 @@ int af_alg_accept(struct sock *sk, struc
+
+ sk2->sk_family = PF_ALG;
+
+- if (nokey || !ask->refcnt++)
++ if (atomic_inc_return_relaxed(&ask->refcnt) == 1)
+ sock_hold(sk);
+- ask->nokey_refcnt += nokey;
++ if (nokey) {
++ atomic_inc(&ask->nokey_refcnt);
++ atomic_set(&alg_sk(sk2)->nokey_refcnt, 1);
++ }
+ alg_sk(sk2)->parent = sk;
+ alg_sk(sk2)->type = type;
+- alg_sk(sk2)->nokey_refcnt = nokey;
+
+ newsock->ops = type->ops;
+ newsock->state = SS_CONNECTED;
+--- a/crypto/algif_aead.c
++++ b/crypto/algif_aead.c
+@@ -388,7 +388,7 @@ static int aead_check_key(struct socket
+ struct alg_sock *ask = alg_sk(sk);
+
+ lock_sock(sk);
+- if (ask->refcnt)
++ if (!atomic_read(&ask->nokey_refcnt))
+ goto unlock_child;
+
+ psk = ask->parent;
+@@ -400,11 +400,8 @@ static int aead_check_key(struct socket
+ if (crypto_aead_get_flags(tfm->aead) & CRYPTO_TFM_NEED_KEY)
+ goto unlock;
+
+- if (!pask->refcnt++)
+- sock_hold(psk);
+-
+- ask->refcnt = 1;
+- sock_put(psk);
++ atomic_dec(&pask->nokey_refcnt);
++ atomic_set(&ask->nokey_refcnt, 0);
+
+ err = 0;
+
+--- a/crypto/algif_hash.c
++++ b/crypto/algif_hash.c
+@@ -306,7 +306,7 @@ static int hash_check_key(struct socket
+ struct alg_sock *ask = alg_sk(sk);
+
+ lock_sock(sk);
+- if (ask->refcnt)
++ if (!atomic_read(&ask->nokey_refcnt))
+ goto unlock_child;
+
+ psk = ask->parent;
+@@ -318,11 +318,8 @@ static int hash_check_key(struct socket
+ if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
+ goto unlock;
+
+- if (!pask->refcnt++)
+- sock_hold(psk);
+-
+- ask->refcnt = 1;
+- sock_put(psk);
++ atomic_dec(&pask->nokey_refcnt);
++ atomic_set(&ask->nokey_refcnt, 0);
+
+ err = 0;
+
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -215,7 +215,7 @@ static int skcipher_check_key(struct soc
+ struct alg_sock *ask = alg_sk(sk);
+
+ lock_sock(sk);
+- if (ask->refcnt)
++ if (!atomic_read(&ask->nokey_refcnt))
+ goto unlock_child;
+
+ psk = ask->parent;
+@@ -227,11 +227,8 @@ static int skcipher_check_key(struct soc
+ if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
+ goto unlock;
+
+- if (!pask->refcnt++)
+- sock_hold(psk);
+-
+- ask->refcnt = 1;
+- sock_put(psk);
++ atomic_dec(&pask->nokey_refcnt);
++ atomic_set(&ask->nokey_refcnt, 0);
+
+ err = 0;
+
+--- a/include/crypto/if_alg.h
++++ b/include/crypto/if_alg.h
+@@ -34,8 +34,8 @@ struct alg_sock {
+
+ struct sock *parent;
+
+- unsigned int refcnt;
+- unsigned int nokey_refcnt;
++ atomic_t refcnt;
++ atomic_t nokey_refcnt;
+
+ const struct af_alg_type *type;
+ void *private;
--- /dev/null
+From e918e570415ced9898a51109000a3f39a6e03be5 Mon Sep 17 00:00:00 2001
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Date: Thu, 25 Jun 2020 05:31:11 +0300
+Subject: tpm_tis: Remove the HID IFX0102
+
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+
+commit e918e570415ced9898a51109000a3f39a6e03be5 upstream.
+
+Acer C720 running Linux v5.3 reports this in klog:
+
+tpm_tis: 1.2 TPM (device-id 0xB, rev-id 16)
+tpm tpm0: tpm_try_transmit: send(): error -5
+tpm tpm0: A TPM error (-5) occurred attempting to determine the timeouts
+tpm_tis tpm_tis: Could not get TPM timeouts and durations
+tpm_tis 00:08: 1.2 TPM (device-id 0xB, rev-id 16)
+tpm tpm0: tpm_try_transmit: send(): error -5
+tpm tpm0: A TPM error (-5) occurred attempting to determine the timeouts
+tpm_tis 00:08: Could not get TPM timeouts and durations
+ima: No TPM chip found, activating TPM-bypass!
+tpm_inf_pnp 00:08: Found TPM with ID IFX0102
+
+% git --no-pager grep IFX0102 drivers/char/tpm
+drivers/char/tpm/tpm_infineon.c: {"IFX0102", 0},
+drivers/char/tpm/tpm_tis.c: {"IFX0102", 0}, /* Infineon */
+
+Obviously IFX0102 was added to the HID table for the TCG TIS driver by
+mistake.
+
+Fixes: 93e1b7d42e1e ("[PATCH] tpm: add HID module parameter")
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=203877
+Cc: stable@vger.kernel.org
+Cc: Kylene Jo Hall <kjhall@us.ibm.com>
+Reported-by: Ferry Toth: <ferry.toth@elsinga.info>
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -242,7 +242,6 @@ static int tpm_tis_pnp_init(struct pnp_d
+ static struct pnp_device_id tpm_pnp_tbl[] = {
+ {"PNP0C31", 0}, /* TPM */
+ {"ATM1200", 0}, /* Atmel */
+- {"IFX0102", 0}, /* Infineon */
+ {"BCM0101", 0}, /* Broadcom */
+ {"BCM0102", 0}, /* Broadcom */
+ {"NSC1200", 0}, /* National */