]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.7-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Jul 2020 11:35:43 +0000 (13:35 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 5 Jul 2020 11:35:43 +0000 (13:35 +0200)
added patches:
crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch
revert-tpm-selftest-cleanup-after-unseal-with-wrong-auth-policy-test.patch
selftests-tpm-use-bin-sh-instead-of-bin-bash.patch
tpm-fix-tis-locality-timeout-problems.patch
tpm_tis-remove-the-hid-ifx0102.patch

queue-5.7/crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch [new file with mode: 0644]
queue-5.7/revert-tpm-selftest-cleanup-after-unseal-with-wrong-auth-policy-test.patch [new file with mode: 0644]
queue-5.7/selftests-tpm-use-bin-sh-instead-of-bin-bash.patch [new file with mode: 0644]
queue-5.7/series
queue-5.7/tpm-fix-tis-locality-timeout-problems.patch [new file with mode: 0644]
queue-5.7/tpm_tis-remove-the-hid-ifx0102.patch [new file with mode: 0644]

diff --git a/queue-5.7/crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch b/queue-5.7/crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch
new file mode 100644 (file)
index 0000000..fae1471
--- /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
+@@ -128,21 +128,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);
+@@ -187,7 +181,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);
+@@ -236,7 +230,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;
+@@ -301,12 +295,14 @@ int af_alg_accept(struct sock *sk, struc
+       if (err)
+               goto unlock;
+-      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
+@@ -384,7 +384,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;
+@@ -396,11 +396,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
+@@ -301,7 +301,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;
+@@ -313,11 +313,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
+@@ -211,7 +211,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;
+@@ -223,11 +223,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
+@@ -29,8 +29,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;
diff --git a/queue-5.7/revert-tpm-selftest-cleanup-after-unseal-with-wrong-auth-policy-test.patch b/queue-5.7/revert-tpm-selftest-cleanup-after-unseal-with-wrong-auth-policy-test.patch
new file mode 100644 (file)
index 0000000..3f89048
--- /dev/null
@@ -0,0 +1,38 @@
+From 5be206eaac9a68992fc3b06fb5dd5634e323de86 Mon Sep 17 00:00:00 2001
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Date: Tue, 23 Jun 2020 00:20:20 +0300
+Subject: Revert "tpm: selftest: cleanup after unseal with wrong auth/policy test"
+
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+
+commit 5be206eaac9a68992fc3b06fb5dd5634e323de86 upstream.
+
+The reverted commit illegitly uses tpm2-tools. External dependencies are
+absolutely forbidden from these tests. There is also the problem that
+clearing is not necessarily wanted behavior if the test/target computer is
+not used only solely for testing.
+
+Fixes: a9920d3bad40 ("tpm: selftest: cleanup after unseal with wrong auth/policy test")
+Cc: Tadeusz Struk <tadeusz.struk@intel.com>
+Cc: stable@vger.kernel.org
+Cc: linux-integrity@vger.kernel.org
+Cc: linux-kselftest@vger.kernel.org
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/testing/selftests/tpm2/test_smoke.sh |    5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/tools/testing/selftests/tpm2/test_smoke.sh
++++ b/tools/testing/selftests/tpm2/test_smoke.sh
+@@ -3,8 +3,3 @@
+ python -m unittest -v tpm2_tests.SmokeTest
+ python -m unittest -v tpm2_tests.AsyncTest
+-
+-CLEAR_CMD=$(which tpm2_clear)
+-if [ -n $CLEAR_CMD ]; then
+-      tpm2_clear -T device
+-fi
diff --git a/queue-5.7/selftests-tpm-use-bin-sh-instead-of-bin-bash.patch b/queue-5.7/selftests-tpm-use-bin-sh-instead-of-bin-bash.patch
new file mode 100644 (file)
index 0000000..b551db7
--- /dev/null
@@ -0,0 +1,41 @@
+From 377ff83083c953dd58c5a030b3c9b5b85d8cc727 Mon Sep 17 00:00:00 2001
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Date: Tue, 23 Jun 2020 00:20:22 +0300
+Subject: selftests: tpm: Use /bin/sh instead of /bin/bash
+
+From: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+
+commit 377ff83083c953dd58c5a030b3c9b5b85d8cc727 upstream.
+
+It's better to use /bin/sh instead of /bin/bash in order to run the tests
+in the BusyBox shell.
+
+Fixes: 6ea3dfe1e073 ("selftests: add TPM 2.0 tests")
+Cc: stable@vger.kernel.org
+Cc: linux-integrity@vger.kernel.org
+Cc: linux-kselftest@vger.kernel.org
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/testing/selftests/tpm2/test_smoke.sh |    2 +-
+ tools/testing/selftests/tpm2/test_space.sh |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/tools/testing/selftests/tpm2/test_smoke.sh
++++ b/tools/testing/selftests/tpm2/test_smoke.sh
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+ # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+ python -m unittest -v tpm2_tests.SmokeTest
+--- a/tools/testing/selftests/tpm2/test_space.sh
++++ b/tools/testing/selftests/tpm2/test_space.sh
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+ # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+ python -m unittest -v tpm2_tests.SpaceTest
index d63d36da25c23d03d7b54ed18dca3222088c35b0..a6590c89d598bdee50212471a17378e8c0862c50 100644 (file)
@@ -38,3 +38,8 @@ nvme-multipath-fix-deadlock-due-to-head-lock.patch
 nvme-multipath-fix-bogus-request-queue-reference-put.patch
 io_uring-fix-current-mm-null-dereference-on-exit.patch
 kgdb-avoid-suspicious-rcu-usage-warning.patch
+revert-tpm-selftest-cleanup-after-unseal-with-wrong-auth-policy-test.patch
+tpm_tis-remove-the-hid-ifx0102.patch
+selftests-tpm-use-bin-sh-instead-of-bin-bash.patch
+tpm-fix-tis-locality-timeout-problems.patch
+crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch
diff --git a/queue-5.7/tpm-fix-tis-locality-timeout-problems.patch b/queue-5.7/tpm-fix-tis-locality-timeout-problems.patch
new file mode 100644 (file)
index 0000000..d7427ae
--- /dev/null
@@ -0,0 +1,73 @@
+From 7862840219058436b80029a0263fd1ef065fb1b3 Mon Sep 17 00:00:00 2001
+From: James Bottomley <James.Bottomley@HansenPartnership.com>
+Date: Thu, 28 May 2020 11:10:57 -0700
+Subject: tpm: Fix TIS locality timeout problems
+
+From: James Bottomley <James.Bottomley@HansenPartnership.com>
+
+commit 7862840219058436b80029a0263fd1ef065fb1b3 upstream.
+
+It has been reported that some TIS based TPMs are giving unexpected
+errors when using the O_NONBLOCK path of the TPM device. The problem
+is that some TPMs don't like it when you get and then relinquish a
+locality (as the tpm_try_get_ops()/tpm_put_ops() pair does) without
+sending a command.  This currently happens all the time in the
+O_NONBLOCK write path. Fix this by moving the tpm_try_get_ops()
+further down the code to after the O_NONBLOCK determination is made.
+This is safe because the priv->buffer_mutex still protects the priv
+state being modified.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=206275
+Fixes: d23d12484307 ("tpm: fix invalid locking in NONBLOCKING mode")
+Reported-by: Mario Limonciello <Mario.Limonciello@dell.com>
+Tested-by: Alex Guzman <alex@guzman.io>
+Cc: stable@vger.kernel.org
+Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm-dev-common.c |   19 +++++++++----------
+ 1 file changed, 9 insertions(+), 10 deletions(-)
+
+--- a/drivers/char/tpm/tpm-dev-common.c
++++ b/drivers/char/tpm/tpm-dev-common.c
+@@ -189,15 +189,6 @@ ssize_t tpm_common_write(struct file *fi
+               goto out;
+       }
+-      /* atomic tpm command send and result receive. We only hold the ops
+-       * lock during this period so that the tpm can be unregistered even if
+-       * the char dev is held open.
+-       */
+-      if (tpm_try_get_ops(priv->chip)) {
+-              ret = -EPIPE;
+-              goto out;
+-      }
+-
+       priv->response_length = 0;
+       priv->response_read = false;
+       *off = 0;
+@@ -211,11 +202,19 @@ ssize_t tpm_common_write(struct file *fi
+       if (file->f_flags & O_NONBLOCK) {
+               priv->command_enqueued = true;
+               queue_work(tpm_dev_wq, &priv->async_work);
+-              tpm_put_ops(priv->chip);
+               mutex_unlock(&priv->buffer_mutex);
+               return size;
+       }
++      /* atomic tpm command send and result receive. We only hold the ops
++       * lock during this period so that the tpm can be unregistered even if
++       * the char dev is held open.
++       */
++      if (tpm_try_get_ops(priv->chip)) {
++              ret = -EPIPE;
++              goto out;
++      }
++
+       ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
+                              sizeof(priv->data_buffer));
+       tpm_put_ops(priv->chip);
diff --git a/queue-5.7/tpm_tis-remove-the-hid-ifx0102.patch b/queue-5.7/tpm_tis-remove-the-hid-ifx0102.patch
new file mode 100644 (file)
index 0000000..07e2bb4
--- /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
+@@ -238,7 +238,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 */