From: Sasha Levin Date: Wed, 10 Feb 2021 16:35:03 +0000 (-0500) Subject: Fixes for 4.4 X-Git-Tag: v4.19.176~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bc008c90986d7a7616d9a9d04da0d233a6bd177d;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.4 Signed-off-by: Sasha Levin --- diff --git a/queue-4.4/af_key-relax-availability-checks-for-skb-size-calcul.patch b/queue-4.4/af_key-relax-availability-checks-for-skb-size-calcul.patch new file mode 100644 index 00000000000..ef438efc3ba --- /dev/null +++ b/queue-4.4/af_key-relax-availability-checks-for-skb-size-calcul.patch @@ -0,0 +1,64 @@ +From 364abd99ee9895ab5458801e0f6a7dc01d985908 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 26 Dec 2020 16:50:20 -0800 +Subject: af_key: relax availability checks for skb size calculation + +From: Cong Wang + +[ Upstream commit afbc293add6466f8f3f0c3d944d85f53709c170f ] + +xfrm_probe_algs() probes kernel crypto modules and changes the +availability of struct xfrm_algo_desc. But there is a small window +where ealg->available and aalg->available get changed between +count_ah_combs()/count_esp_combs() and dump_ah_combs()/dump_esp_combs(), +in this case we may allocate a smaller skb but later put a larger +amount of data and trigger the panic in skb_put(). + +Fix this by relaxing the checks when counting the size, that is, +skipping the test of ->available. We may waste some memory for a few +of sizeof(struct sadb_comb), but it is still much better than a panic. + +Reported-by: syzbot+b2bf2652983d23734c5c@syzkaller.appspotmail.com +Cc: Steffen Klassert +Cc: Herbert Xu +Signed-off-by: Cong Wang +Signed-off-by: Steffen Klassert +Signed-off-by: Sasha Levin +--- + net/key/af_key.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/net/key/af_key.c b/net/key/af_key.c +index 76a008b1cbe5f..adc93329e6aac 100644 +--- a/net/key/af_key.c ++++ b/net/key/af_key.c +@@ -2933,7 +2933,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t) + break; + if (!aalg->pfkey_supported) + continue; +- if (aalg_tmpl_set(t, aalg) && aalg->available) ++ if (aalg_tmpl_set(t, aalg)) + sz += sizeof(struct sadb_comb); + } + return sz + sizeof(struct sadb_prop); +@@ -2951,7 +2951,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) + if (!ealg->pfkey_supported) + continue; + +- if (!(ealg_tmpl_set(t, ealg) && ealg->available)) ++ if (!(ealg_tmpl_set(t, ealg))) + continue; + + for (k = 1; ; k++) { +@@ -2962,7 +2962,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t) + if (!aalg->pfkey_supported) + continue; + +- if (aalg_tmpl_set(t, aalg) && aalg->available) ++ if (aalg_tmpl_set(t, aalg)) + sz += sizeof(struct sadb_comb); + } + } +-- +2.27.0 + diff --git a/queue-4.4/iwlwifi-mvm-guard-against-device-removal-in-reprobe.patch b/queue-4.4/iwlwifi-mvm-guard-against-device-removal-in-reprobe.patch new file mode 100644 index 00000000000..eee458c6d99 --- /dev/null +++ b/queue-4.4/iwlwifi-mvm-guard-against-device-removal-in-reprobe.patch @@ -0,0 +1,49 @@ +From b37865da5e5b132d4684208440367a86bce83ea5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jan 2021 14:52:41 +0200 +Subject: iwlwifi: mvm: guard against device removal in reprobe + +From: Johannes Berg + +[ Upstream commit 7a21b1d4a728a483f07c638ccd8610d4b4f12684 ] + +If we get into a problem severe enough to attempt a reprobe, +we schedule a worker to do that. However, if the problem gets +more severe and the device is actually destroyed before this +worker has a chance to run, we use a free device. Bump up the +reference count of the device until the worker runs to avoid +this situation. + +Signed-off-by: Johannes Berg +Signed-off-by: Luca Coelho +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/iwlwifi.20210122144849.871f0892e4b2.I94819e11afd68d875f3e242b98bef724b8236f1e@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/iwlwifi/mvm/ops.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c +index 13c97f665ba88..bb81261de45fa 100644 +--- a/drivers/net/wireless/iwlwifi/mvm/ops.c ++++ b/drivers/net/wireless/iwlwifi/mvm/ops.c +@@ -909,6 +909,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk) + reprobe = container_of(wk, struct iwl_mvm_reprobe, work); + if (device_reprobe(reprobe->dev)) + dev_err(reprobe->dev, "reprobe failed!\n"); ++ put_device(reprobe->dev); + kfree(reprobe); + module_put(THIS_MODULE); + } +@@ -991,7 +992,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) + module_put(THIS_MODULE); + return; + } +- reprobe->dev = mvm->trans->dev; ++ reprobe->dev = get_device(mvm->trans->dev); + INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); + schedule_work(&reprobe->work); + } else if (mvm->cur_ucode == IWL_UCODE_REGULAR) { +-- +2.27.0 + diff --git a/queue-4.4/iwlwifi-pcie-add-a-null-check-in-iwl_pcie_txq_unmap.patch b/queue-4.4/iwlwifi-pcie-add-a-null-check-in-iwl_pcie_txq_unmap.patch new file mode 100644 index 00000000000..a80768df14c --- /dev/null +++ b/queue-4.4/iwlwifi-pcie-add-a-null-check-in-iwl_pcie_txq_unmap.patch @@ -0,0 +1,40 @@ +From 8d6c450aa2816facbd5c143a5e7ae7a2ae197608 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 15 Jan 2021 13:05:55 +0200 +Subject: iwlwifi: pcie: add a NULL check in iwl_pcie_txq_unmap + +From: Emmanuel Grumbach + +[ Upstream commit 98c7d21f957b10d9c07a3a60a3a5a8f326a197e5 ] + +I hit a NULL pointer exception in this function when the +init flow went really bad. + +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Luca Coelho +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/iwlwifi.20210115130252.2e8da9f2c132.I0234d4b8ddaf70aaa5028a20c863255e05bc1f84@changeid +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/iwlwifi/pcie/tx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c +index 8dfe6b2bc7031..cb03c2855019b 100644 +--- a/drivers/net/wireless/iwlwifi/pcie/tx.c ++++ b/drivers/net/wireless/iwlwifi/pcie/tx.c +@@ -585,6 +585,11 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) + struct iwl_txq *txq = &trans_pcie->txq[txq_id]; + struct iwl_queue *q = &txq->q; + ++ if (!txq) { ++ IWL_ERR(trans, "Trying to free a queue that wasn't allocated?\n"); ++ return; ++ } ++ + spin_lock_bh(&txq->lock); + while (q->write_ptr != q->read_ptr) { + IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", +-- +2.27.0 + diff --git a/queue-4.4/series b/queue-4.4/series index 16ff1cdf362..c79197f99e9 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -1 +1,6 @@ fgraph-initialize-tracing_graph_pause-at-task-creation.patch +af_key-relax-availability-checks-for-skb-size-calcul.patch +iwlwifi-pcie-add-a-null-check-in-iwl_pcie_txq_unmap.patch +iwlwifi-mvm-guard-against-device-removal-in-reprobe.patch +sunrpc-move-simple_get_bytes-and-simple_get_netobj-i.patch +sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch diff --git a/queue-4.4/sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch b/queue-4.4/sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch new file mode 100644 index 00000000000..c33db83e4a7 --- /dev/null +++ b/queue-4.4/sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch @@ -0,0 +1,79 @@ +From f08171aacf66078117725642696c42a4c7759ce1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 16:17:24 -0500 +Subject: SUNRPC: Handle 0 length opaque XDR object data properly + +From: Dave Wysochanski + +[ Upstream commit e4a7d1f7707eb44fd953a31dd59eff82009d879c ] + +When handling an auth_gss downcall, it's possible to get 0-length +opaque object for the acceptor. In the case of a 0-length XDR +object, make sure simple_get_netobj() fills in dest->data = NULL, +and does not continue to kmemdup() which will set +dest->data = ZERO_SIZE_PTR for the acceptor. + +The trace event code can handle NULL but not ZERO_SIZE_PTR for a +string, and so without this patch the rpcgss_context trace event +will crash the kernel as follows: + +[ 162.887992] BUG: kernel NULL pointer dereference, address: 0000000000000010 +[ 162.898693] #PF: supervisor read access in kernel mode +[ 162.900830] #PF: error_code(0x0000) - not-present page +[ 162.902940] PGD 0 P4D 0 +[ 162.904027] Oops: 0000 [#1] SMP PTI +[ 162.905493] CPU: 4 PID: 4321 Comm: rpc.gssd Kdump: loaded Not tainted 5.10.0 #133 +[ 162.908548] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 +[ 162.910978] RIP: 0010:strlen+0x0/0x20 +[ 162.912505] Code: 48 89 f9 74 09 48 83 c1 01 80 39 00 75 f7 31 d2 44 0f b6 04 16 44 88 04 11 48 83 c2 01 45 84 c0 75 ee c3 0f 1f 80 00 00 00 00 <80> 3f 00 74 10 48 89 f8 48 83 c0 01 80 38 00 75 f7 48 29 f8 c3 31 +[ 162.920101] RSP: 0018:ffffaec900c77d90 EFLAGS: 00010202 +[ 162.922263] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000fffde697 +[ 162.925158] RDX: 000000000000002f RSI: 0000000000000080 RDI: 0000000000000010 +[ 162.928073] RBP: 0000000000000010 R08: 0000000000000e10 R09: 0000000000000000 +[ 162.930976] R10: ffff8e698a590cb8 R11: 0000000000000001 R12: 0000000000000e10 +[ 162.933883] R13: 00000000fffde697 R14: 000000010034d517 R15: 0000000000070028 +[ 162.936777] FS: 00007f1e1eb93700(0000) GS:ffff8e6ab7d00000(0000) knlGS:0000000000000000 +[ 162.940067] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 162.942417] CR2: 0000000000000010 CR3: 0000000104eba000 CR4: 00000000000406e0 +[ 162.945300] Call Trace: +[ 162.946428] trace_event_raw_event_rpcgss_context+0x84/0x140 [auth_rpcgss] +[ 162.949308] ? __kmalloc_track_caller+0x35/0x5a0 +[ 162.951224] ? gss_pipe_downcall+0x3a3/0x6a0 [auth_rpcgss] +[ 162.953484] gss_pipe_downcall+0x585/0x6a0 [auth_rpcgss] +[ 162.955953] rpc_pipe_write+0x58/0x70 [sunrpc] +[ 162.957849] vfs_write+0xcb/0x2c0 +[ 162.959264] ksys_write+0x68/0xe0 +[ 162.960706] do_syscall_64+0x33/0x40 +[ 162.962238] entry_SYSCALL_64_after_hwframe+0x44/0xa9 +[ 162.964346] RIP: 0033:0x7f1e1f1e57df + +Signed-off-by: Dave Wysochanski +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + net/sunrpc/auth_gss/auth_gss_internal.h | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/sunrpc/auth_gss/auth_gss_internal.h b/net/sunrpc/auth_gss/auth_gss_internal.h +index c5603242b54bf..f6d9631bd9d00 100644 +--- a/net/sunrpc/auth_gss/auth_gss_internal.h ++++ b/net/sunrpc/auth_gss/auth_gss_internal.h +@@ -34,9 +34,12 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) + q = (const void *)((const char *)p + len); + if (unlikely(q > end || q < p)) + return ERR_PTR(-EFAULT); +- dest->data = kmemdup(p, len, GFP_NOFS); +- if (unlikely(dest->data == NULL)) +- return ERR_PTR(-ENOMEM); ++ if (len) { ++ dest->data = kmemdup(p, len, GFP_NOFS); ++ if (unlikely(dest->data == NULL)) ++ return ERR_PTR(-ENOMEM); ++ } else ++ dest->data = NULL; + dest->len = len; + return q; + } +-- +2.27.0 + diff --git a/queue-4.4/sunrpc-move-simple_get_bytes-and-simple_get_netobj-i.patch b/queue-4.4/sunrpc-move-simple_get_bytes-and-simple_get_netobj-i.patch new file mode 100644 index 00000000000..66988420fd3 --- /dev/null +++ b/queue-4.4/sunrpc-move-simple_get_bytes-and-simple_get_netobj-i.patch @@ -0,0 +1,190 @@ +From b976aaa4e55bf71b0785bdeec334ede563d56a94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Jan 2021 16:17:23 -0500 +Subject: SUNRPC: Move simple_get_bytes and simple_get_netobj into private + header + +From: Dave Wysochanski + +[ Upstream commit ba6dfce47c4d002d96cd02a304132fca76981172 ] + +Remove duplicated helper functions to parse opaque XDR objects +and place inside new file net/sunrpc/auth_gss/auth_gss_internal.h. +In the new file carry the license and copyright from the source file +net/sunrpc/auth_gss/auth_gss.c. Finally, update the comment inside +include/linux/sunrpc/xdr.h since lockd is not the only user of +struct xdr_netobj. + +Signed-off-by: Dave Wysochanski +Signed-off-by: Trond Myklebust +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/xdr.h | 3 +- + net/sunrpc/auth_gss/auth_gss.c | 30 +----------------- + net/sunrpc/auth_gss/auth_gss_internal.h | 42 +++++++++++++++++++++++++ + net/sunrpc/auth_gss/gss_krb5_mech.c | 31 ++---------------- + 4 files changed, 46 insertions(+), 60 deletions(-) + create mode 100644 net/sunrpc/auth_gss/auth_gss_internal.h + +diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h +index 70c6b92e15a7c..8def5e0a491fa 100644 +--- a/include/linux/sunrpc/xdr.h ++++ b/include/linux/sunrpc/xdr.h +@@ -23,8 +23,7 @@ + #define XDR_QUADLEN(l) (((l) + 3) >> 2) + + /* +- * Generic opaque `network object.' At the kernel level, this type +- * is used only by lockd. ++ * Generic opaque `network object.' + */ + #define XDR_MAX_NETOBJ 1024 + struct xdr_netobj { +diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c +index 62fca77bf3c70..7bde2976307ed 100644 +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -53,6 +53,7 @@ + #include + #include + ++#include "auth_gss_internal.h" + #include "../netns.h" + + static const struct rpc_authops authgss_ops; +@@ -147,35 +148,6 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) + clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); + } + +-static const void * +-simple_get_bytes(const void *p, const void *end, void *res, size_t len) +-{ +- const void *q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- memcpy(res, p, len); +- return q; +-} +- +-static inline const void * +-simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) +-{ +- const void *q; +- unsigned int len; +- +- p = simple_get_bytes(p, end, &len, sizeof(len)); +- if (IS_ERR(p)) +- return p; +- q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- dest->data = kmemdup(p, len, GFP_NOFS); +- if (unlikely(dest->data == NULL)) +- return ERR_PTR(-ENOMEM); +- dest->len = len; +- return q; +-} +- + static struct gss_cl_ctx * + gss_cred_get_ctx(struct rpc_cred *cred) + { +diff --git a/net/sunrpc/auth_gss/auth_gss_internal.h b/net/sunrpc/auth_gss/auth_gss_internal.h +new file mode 100644 +index 0000000000000..c5603242b54bf +--- /dev/null ++++ b/net/sunrpc/auth_gss/auth_gss_internal.h +@@ -0,0 +1,42 @@ ++// SPDX-License-Identifier: BSD-3-Clause ++/* ++ * linux/net/sunrpc/auth_gss/auth_gss_internal.h ++ * ++ * Internal definitions for RPCSEC_GSS client authentication ++ * ++ * Copyright (c) 2000 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ */ ++#include ++#include ++#include ++ ++static inline const void * ++simple_get_bytes(const void *p, const void *end, void *res, size_t len) ++{ ++ const void *q = (const void *)((const char *)p + len); ++ if (unlikely(q > end || q < p)) ++ return ERR_PTR(-EFAULT); ++ memcpy(res, p, len); ++ return q; ++} ++ ++static inline const void * ++simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) ++{ ++ const void *q; ++ unsigned int len; ++ ++ p = simple_get_bytes(p, end, &len, sizeof(len)); ++ if (IS_ERR(p)) ++ return p; ++ q = (const void *)((const char *)p + len); ++ if (unlikely(q > end || q < p)) ++ return ERR_PTR(-EFAULT); ++ dest->data = kmemdup(p, len, GFP_NOFS); ++ if (unlikely(dest->data == NULL)) ++ return ERR_PTR(-ENOMEM); ++ dest->len = len; ++ return q; ++} +diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c +index 28db442a0034a..89e616da161fd 100644 +--- a/net/sunrpc/auth_gss/gss_krb5_mech.c ++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c +@@ -45,6 +45,8 @@ + #include + #include + ++#include "auth_gss_internal.h" ++ + #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) + # define RPCDBG_FACILITY RPCDBG_AUTH + #endif +@@ -186,35 +188,6 @@ get_gss_krb5_enctype(int etype) + return NULL; + } + +-static const void * +-simple_get_bytes(const void *p, const void *end, void *res, int len) +-{ +- const void *q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- memcpy(res, p, len); +- return q; +-} +- +-static const void * +-simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res) +-{ +- const void *q; +- unsigned int len; +- +- p = simple_get_bytes(p, end, &len, sizeof(len)); +- if (IS_ERR(p)) +- return p; +- q = (const void *)((const char *)p + len); +- if (unlikely(q > end || q < p)) +- return ERR_PTR(-EFAULT); +- res->data = kmemdup(p, len, GFP_NOFS); +- if (unlikely(res->data == NULL)) +- return ERR_PTR(-ENOMEM); +- res->len = len; +- return q; +-} +- + static inline const void * + get_key(const void *p, const void *end, + struct krb5_ctx *ctx, struct crypto_blkcipher **res) +-- +2.27.0 +