From 2850707009a42e676f223326ac82c42b5c036f2d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 5 Jul 2020 16:02:31 +0200 Subject: [PATCH] 4.19-stable patches 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 --- ...in-af_alg_accept-due-to-bh_lock_sock.patch | 191 ++++++++++++++++++ queue-4.19/series | 2 + .../tpm_tis-remove-the-hid-ifx0102.patch | 52 +++++ 3 files changed, 245 insertions(+) create mode 100644 queue-4.19/crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch create mode 100644 queue-4.19/tpm_tis-remove-the-hid-ifx0102.patch 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 index 00000000000..8c747f3faaf --- /dev/null +++ b/queue-4.19/crypto-af_alg-fix-use-after-free-in-af_alg_accept-due-to-bh_lock_sock.patch @@ -0,0 +1,191 @@ +From 34c86f4c4a7be3b3e35aa48bd18299d4c756064d Mon Sep 17 00:00:00 2001 +From: Herbert Xu +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 + +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 +Reported-by: Mauricio Faria de Oliveira +Fixes: 37f96694cf73 ("crypto: af_alg - Use bh_lock_sock in...") +Cc: +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/series b/queue-4.19/series index 67e8d3bf92d..dc4eb2fa45a 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -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 index 00000000000..99935449dac --- /dev/null +++ b/queue-4.19/tpm_tis-remove-the-hid-ifx0102.patch @@ -0,0 +1,52 @@ +From e918e570415ced9898a51109000a3f39a6e03be5 Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Thu, 25 Jun 2020 05:31:11 +0300 +Subject: tpm_tis: Remove the HID IFX0102 + +From: Jarkko Sakkinen + +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 +Reported-by: Ferry Toth: +Reviewed-by: Jerry Snitselaar +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ -- 2.47.3