]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Jul 2020 14:02:31 +0000 (16:02 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Jul 2020 14:02:31 +0000 (16:02 +0200)
added patches:
crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch
tpm_tis-remove-the-hid-ifx0102.patch

queue-4.19/crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/tpm_tis-remove-the-hid-ifx0102.patch [new file with mode: 0644]

diff --git a/queue-4.19/crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch b/queue-4.19/crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch
new file mode 100644 (file)
index 0000000..8c747f3
--- /dev/null
@@ -0,0 +1,191 @@
+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;
index 67e8d3bf92da25e9d35c26fcc01d47cb07d0d848..dc4eb2fa45a5ea209b48111ba42314284a5f1e95 100644 (file)
@@ -10,3 +10,5 @@ nvme-multipath-set-bdi-capabilities-once.patch
 nvme-fix-possible-deadlock-when-i-o-is-blocked.patch
 nvme-multipath-fix-deadlock-between-ana_work-and-sca.patch
 kgdb-avoid-suspicious-rcu-usage-warning.patch
+tpm_tis-remove-the-hid-ifx0102.patch
+crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch
diff --git a/queue-4.19/tpm_tis-remove-the-hid-ifx0102.patch b/queue-4.19/tpm_tis-remove-the-hid-ifx0102.patch
new file mode 100644 (file)
index 0000000..9993544
--- /dev/null
@@ -0,0 +1,52 @@
+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 */