From fc2349cb307050953daad4b386264d7c7ec85b67 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 10 Dec 2020 14:32:30 +0100 Subject: [PATCH] 5.9-stable patches added patches: asoc-wm_adsp-fix-error-return-code-in-wm_adsp_load.patch can-af_can-can_rx_unregister-remove-warn-statement-from-list-operation-sanity-check.patch dm-writecache-remove-bug-and-fail-gracefully-instead.patch gfs2-check-for-empty-rgrp-tree-in-gfs2_ri_update.patch gfs2-don-t-freeze-the-file-system-during-unmount.patch gfs2-fix-deadlock-dumping-resource-group-glocks.patch i2c-qcom-fix-irq-error-misassignement.patch i2c-qup-fix-error-return-code-in-qup_i2c_bam_schedule_desc.patch input-i8042-fix-error-return-code-in-i8042_setup_aux.patch netfilter-ipset-prevent-uninit-value-in-hash_ip6_add.patch netfilter-nf_tables-avoid-false-postive-lockdep-splat.patch netfilter-nftables_offload-build-mask-based-from-the-matching-bytes.patch netfilter-nftables_offload-set-address-type-in-control-dissector.patch rtw88-debug-fix-uninitialized-memory-in-debugfs-code.patch tipc-fix-a-deadlock-when-flushing-scheduled-work.patch --- ...ix-error-return-code-in-wm_adsp_load.patch | 35 +++ ...ent-from-list-operation-sanity-check.patch | 51 +++ ...move-bug-and-fail-gracefully-instead.patch | 37 +++ ...or-empty-rgrp-tree-in-gfs2_ri_update.patch | 37 +++ ...reeze-the-file-system-during-unmount.patch | 46 +++ ...adlock-dumping-resource-group-glocks.patch | 42 +++ ...2c-qcom-fix-irq-error-misassignement.patch | 40 +++ ...rn-code-in-qup_i2c_bam_schedule_desc.patch | 35 +++ ...error-return-code-in-i8042_setup_aux.patch | 37 +++ ...prevent-uninit-value-in-hash_ip6_add.patch | 159 ++++++++++ ...es-avoid-false-postive-lockdep-splat.patch | 45 +++ ...d-mask-based-from-the-matching-bytes.patch | 290 ++++++++++++++++++ ...et-address-type-in-control-dissector.patch | 114 +++++++ ...uninitialized-memory-in-debugfs-code.patch | 34 ++ queue-5.9/series | 15 + ...eadlock-when-flushing-scheduled-work.patch | 171 +++++++++++ 16 files changed, 1188 insertions(+) create mode 100644 queue-5.9/asoc-wm_adsp-fix-error-return-code-in-wm_adsp_load.patch create mode 100644 queue-5.9/can-af_can-can_rx_unregister-remove-warn-statement-from-list-operation-sanity-check.patch create mode 100644 queue-5.9/dm-writecache-remove-bug-and-fail-gracefully-instead.patch create mode 100644 queue-5.9/gfs2-check-for-empty-rgrp-tree-in-gfs2_ri_update.patch create mode 100644 queue-5.9/gfs2-don-t-freeze-the-file-system-during-unmount.patch create mode 100644 queue-5.9/gfs2-fix-deadlock-dumping-resource-group-glocks.patch create mode 100644 queue-5.9/i2c-qcom-fix-irq-error-misassignement.patch create mode 100644 queue-5.9/i2c-qup-fix-error-return-code-in-qup_i2c_bam_schedule_desc.patch create mode 100644 queue-5.9/input-i8042-fix-error-return-code-in-i8042_setup_aux.patch create mode 100644 queue-5.9/netfilter-ipset-prevent-uninit-value-in-hash_ip6_add.patch create mode 100644 queue-5.9/netfilter-nf_tables-avoid-false-postive-lockdep-splat.patch create mode 100644 queue-5.9/netfilter-nftables_offload-build-mask-based-from-the-matching-bytes.patch create mode 100644 queue-5.9/netfilter-nftables_offload-set-address-type-in-control-dissector.patch create mode 100644 queue-5.9/rtw88-debug-fix-uninitialized-memory-in-debugfs-code.patch create mode 100644 queue-5.9/tipc-fix-a-deadlock-when-flushing-scheduled-work.patch diff --git a/queue-5.9/asoc-wm_adsp-fix-error-return-code-in-wm_adsp_load.patch b/queue-5.9/asoc-wm_adsp-fix-error-return-code-in-wm_adsp_load.patch new file mode 100644 index 00000000000..e61f719e71b --- /dev/null +++ b/queue-5.9/asoc-wm_adsp-fix-error-return-code-in-wm_adsp_load.patch @@ -0,0 +1,35 @@ +From 3fba05a2832f93b4d0cd4204f771fdae0d823114 Mon Sep 17 00:00:00 2001 +From: Luo Meng +Date: Mon, 23 Nov 2020 21:38:39 +0800 +Subject: ASoC: wm_adsp: fix error return code in wm_adsp_load() + +From: Luo Meng + +commit 3fba05a2832f93b4d0cd4204f771fdae0d823114 upstream. + +Fix to return a negative error code from the error handling case +instead of 0 in function wm_adsp_load(), as done elsewhere in this +function. + +Fixes: 170b1e123f38 ("ASoC: wm_adsp: Add support for new Halo core DSPs") +Reported-by: Hulk Robot +Signed-off-by: Luo Meng +Acked-by: Richard Fitzgerald +Link: https://lore.kernel.org/r/20201123133839.4073787-1-luomeng12@huawei.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/wm_adsp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/soc/codecs/wm_adsp.c ++++ b/sound/soc/codecs/wm_adsp.c +@@ -1937,6 +1937,7 @@ static int wm_adsp_load(struct wm_adsp * + mem = wm_adsp_find_region(dsp, type); + if (!mem) { + adsp_err(dsp, "No region of type: %x\n", type); ++ ret = -EINVAL; + goto out_fw; + } + diff --git a/queue-5.9/can-af_can-can_rx_unregister-remove-warn-statement-from-list-operation-sanity-check.patch b/queue-5.9/can-af_can-can_rx_unregister-remove-warn-statement-from-list-operation-sanity-check.patch new file mode 100644 index 00000000000..fd2dc0b112a --- /dev/null +++ b/queue-5.9/can-af_can-can_rx_unregister-remove-warn-statement-from-list-operation-sanity-check.patch @@ -0,0 +1,51 @@ +From d73ff9b7c4eacaba0fd956d14882bcae970f8307 Mon Sep 17 00:00:00 2001 +From: Oliver Hartkopp +Date: Thu, 26 Nov 2020 20:21:40 +0100 +Subject: can: af_can: can_rx_unregister(): remove WARN() statement from list operation sanity check + +From: Oliver Hartkopp + +commit d73ff9b7c4eacaba0fd956d14882bcae970f8307 upstream. + +To detect potential bugs in CAN protocol implementations (double removal of +receiver entries) a WARN() statement has been used if no matching list item was +found for removal. + +The fault injection issued by syzkaller was able to create a situation where +the closing of a socket runs simultaneously to the notifier call chain for +removing the CAN network device in use. + +This case is very unlikely in real life but it doesn't break anything. +Therefore we just replace the WARN() statement with pr_warn() to preserve the +notification for the CAN protocol development. + +Reported-by: syzbot+381d06e0c8eaacb8706f@syzkaller.appspotmail.com +Reported-by: syzbot+d0ddd88c9a7432f041e6@syzkaller.appspotmail.com +Reported-by: syzbot+76d62d3b8162883c7d11@syzkaller.appspotmail.com +Signed-off-by: Oliver Hartkopp +Link: https://lore.kernel.org/r/20201126192140.14350-1-socketcan@hartkopp.net +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + net/can/af_can.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/net/can/af_can.c ++++ b/net/can/af_can.c +@@ -541,10 +541,13 @@ void can_rx_unregister(struct net *net, + + /* Check for bugs in CAN protocol implementations using af_can.c: + * 'rcv' will be NULL if no matching list item was found for removal. ++ * As this case may potentially happen when closing a socket while ++ * the notifier for removing the CAN netdev is running we just print ++ * a warning here. + */ + if (!rcv) { +- WARN(1, "BUG: receive list entry not found for dev %s, id %03X, mask %03X\n", +- DNAME(dev), can_id, mask); ++ pr_warn("can: receive list entry not found for dev %s, id %03X, mask %03X\n", ++ DNAME(dev), can_id, mask); + goto out; + } + diff --git a/queue-5.9/dm-writecache-remove-bug-and-fail-gracefully-instead.patch b/queue-5.9/dm-writecache-remove-bug-and-fail-gracefully-instead.patch new file mode 100644 index 00000000000..d422e3e78f2 --- /dev/null +++ b/queue-5.9/dm-writecache-remove-bug-and-fail-gracefully-instead.patch @@ -0,0 +1,37 @@ +From 857c4c0a8b2888d806f4308c58f59a6a81a1dee9 Mon Sep 17 00:00:00 2001 +From: Mike Snitzer +Date: Fri, 13 Nov 2020 14:52:28 -0800 +Subject: dm writecache: remove BUG() and fail gracefully instead + +From: Mike Snitzer + +commit 857c4c0a8b2888d806f4308c58f59a6a81a1dee9 upstream. + +Building on arch/s390/ results in this build error: + +cc1: some warnings being treated as errors +../drivers/md/dm-writecache.c: In function 'persistent_memory_claim': +../drivers/md/dm-writecache.c:323:1: error: no return statement in function returning non-void [-Werror=return-type] + +Fix this by replacing the BUG() with an -EOPNOTSUPP return. + +Fixes: 48debafe4f2f ("dm: add writecache target") +Reported-by: Randy Dunlap +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-writecache.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/dm-writecache.c ++++ b/drivers/md/dm-writecache.c +@@ -319,7 +319,7 @@ err1: + #else + static int persistent_memory_claim(struct dm_writecache *wc) + { +- BUG(); ++ return -EOPNOTSUPP; + } + #endif + diff --git a/queue-5.9/gfs2-check-for-empty-rgrp-tree-in-gfs2_ri_update.patch b/queue-5.9/gfs2-check-for-empty-rgrp-tree-in-gfs2_ri_update.patch new file mode 100644 index 00000000000..a21f95d33d1 --- /dev/null +++ b/queue-5.9/gfs2-check-for-empty-rgrp-tree-in-gfs2_ri_update.patch @@ -0,0 +1,37 @@ +From 778721510e84209f78e31e2ccb296ae36d623f5e Mon Sep 17 00:00:00 2001 +From: Bob Peterson +Date: Tue, 24 Nov 2020 10:44:36 -0500 +Subject: gfs2: check for empty rgrp tree in gfs2_ri_update + +From: Bob Peterson + +commit 778721510e84209f78e31e2ccb296ae36d623f5e upstream. + +If gfs2 tries to mount a (corrupt) file system that has no resource +groups it still tries to set preferences on the first one, which causes +a kernel null pointer dereference. This patch adds a check to function +gfs2_ri_update so this condition is detected and reported back as an +error. + +Reported-by: syzbot+e3f23ce40269a4c9053a@syzkaller.appspotmail.com +Signed-off-by: Bob Peterson +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Greg Kroah-Hartman + +--- + fs/gfs2/rgrp.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/gfs2/rgrp.c ++++ b/fs/gfs2/rgrp.c +@@ -989,6 +989,10 @@ static int gfs2_ri_update(struct gfs2_in + if (error < 0) + return error; + ++ if (RB_EMPTY_ROOT(&sdp->sd_rindex_tree)) { ++ fs_err(sdp, "no resource groups found in the file system.\n"); ++ return -ENOENT; ++ } + set_rgrp_preferences(sdp); + + sdp->sd_rindex_uptodate = 1; diff --git a/queue-5.9/gfs2-don-t-freeze-the-file-system-during-unmount.patch b/queue-5.9/gfs2-don-t-freeze-the-file-system-during-unmount.patch new file mode 100644 index 00000000000..5892889c1d3 --- /dev/null +++ b/queue-5.9/gfs2-don-t-freeze-the-file-system-during-unmount.patch @@ -0,0 +1,46 @@ +From f39e7d3aae2934b1cfdd209b54c508e2552e9531 Mon Sep 17 00:00:00 2001 +From: Bob Peterson +Date: Tue, 24 Nov 2020 10:41:40 -0600 +Subject: gfs2: Don't freeze the file system during unmount + +From: Bob Peterson + +commit f39e7d3aae2934b1cfdd209b54c508e2552e9531 upstream. + +GFS2's freeze/thaw mechanism uses a special freeze glock to control its +operation. It does this with a sync glock operation (glops.c) called +freeze_go_sync. When the freeze glock is demoted (glock's do_xmote) the +glops function causes the file system to be frozen. This is intended. However, +GFS2's mount and unmount processes also hold the freeze glock to prevent other +processes, perhaps on different cluster nodes, from mounting the frozen file +system in read-write mode. + +Before this patch, there was no check in freeze_go_sync for whether a freeze +in intended or whether the glock demote was caused by a normal unmount. +So it was trying to freeze the file system it's trying to unmount, which +ends up in a deadlock. + +This patch adds an additional check to freeze_go_sync so that demotes of the +freeze glock are ignored if they come from the unmount process. + +Fixes: 20b329129009 ("gfs2: Fix regression in freeze_go_sync") +Signed-off-by: Bob Peterson +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Greg Kroah-Hartman + +--- + fs/gfs2/glops.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/gfs2/glops.c ++++ b/fs/gfs2/glops.c +@@ -551,7 +551,8 @@ static int freeze_go_sync(struct gfs2_gl + * Once thawed, the work func acquires the freeze glock in + * SH and everybody goes back to thawed. + */ +- if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp)) { ++ if (gl->gl_state == LM_ST_SHARED && !gfs2_withdrawn(sdp) && ++ !test_bit(SDF_NORECOVERY, &sdp->sd_flags)) { + atomic_set(&sdp->sd_freeze_state, SFS_STARTING_FREEZE); + error = freeze_super(sdp->sd_vfs); + if (error) { diff --git a/queue-5.9/gfs2-fix-deadlock-dumping-resource-group-glocks.patch b/queue-5.9/gfs2-fix-deadlock-dumping-resource-group-glocks.patch new file mode 100644 index 00000000000..6f92d866667 --- /dev/null +++ b/queue-5.9/gfs2-fix-deadlock-dumping-resource-group-glocks.patch @@ -0,0 +1,42 @@ +From 16e6281b6b22b0178eab95c6a82502d7b10f67b8 Mon Sep 17 00:00:00 2001 +From: Alexander Aring +Date: Sun, 22 Nov 2020 18:10:24 -0500 +Subject: gfs2: Fix deadlock dumping resource group glocks + +From: Alexander Aring + +commit 16e6281b6b22b0178eab95c6a82502d7b10f67b8 upstream. + +Commit 0e539ca1bbbe ("gfs2: Fix NULL pointer dereference in gfs2_rgrp_dump") +introduced additional locking in gfs2_rgrp_go_dump, which is also used for +dumping resource group glocks via debugfs. However, on that code path, the +glock spin lock is already taken in dump_glock, and taking it again in +gfs2_glock2rgrp leads to deadlock. This can be reproduced with: + + $ mkfs.gfs2 -O -p lock_nolock /dev/FOO + $ mount /dev/FOO /mnt/foo + $ touch /mnt/foo/bar + $ cat /sys/kernel/debug/gfs2/FOO/glocks + +Fix that by not taking the glock spin lock inside the go_dump callback. + +Fixes: 0e539ca1bbbe ("gfs2: Fix NULL pointer dereference in gfs2_rgrp_dump") +Signed-off-by: Alexander Aring +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Greg Kroah-Hartman + +--- + fs/gfs2/glops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/gfs2/glops.c ++++ b/fs/gfs2/glops.c +@@ -230,7 +230,7 @@ static void rgrp_go_inval(struct gfs2_gl + static void gfs2_rgrp_go_dump(struct seq_file *seq, struct gfs2_glock *gl, + const char *fs_id_buf) + { +- struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl); ++ struct gfs2_rgrpd *rgd = gl->gl_object; + + if (rgd) + gfs2_rgrp_dump(seq, rgd, fs_id_buf); diff --git a/queue-5.9/i2c-qcom-fix-irq-error-misassignement.patch b/queue-5.9/i2c-qcom-fix-irq-error-misassignement.patch new file mode 100644 index 00000000000..a498e5bc11e --- /dev/null +++ b/queue-5.9/i2c-qcom-fix-irq-error-misassignement.patch @@ -0,0 +1,40 @@ +From 14718b3e129b058cb716a60c6faf40ef68661c54 Mon Sep 17 00:00:00 2001 +From: Robert Foss +Date: Mon, 30 Nov 2020 11:04:45 +0100 +Subject: i2c: qcom: Fix IRQ error misassignement + +From: Robert Foss + +commit 14718b3e129b058cb716a60c6faf40ef68661c54 upstream. + +During cci_isr() errors read from register fields belonging to +i2c master1 are currently assigned to the status field belonging to +i2c master0. This patch corrects this error, and always assigns +master1 errors to the status field of master1. + +Fixes: e517526195de ("i2c: Add Qualcomm CCI I2C driver") +Reported-by: Loic Poulain +Suggested-by: Loic Poulain +Signed-off-by: Robert Foss +Reviewed-by: Manivannan Sadhasivam +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-qcom-cci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/i2c/busses/i2c-qcom-cci.c ++++ b/drivers/i2c/busses/i2c-qcom-cci.c +@@ -194,9 +194,9 @@ static irqreturn_t cci_isr(int irq, void + if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M1_ERROR)) { + if (val & CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR || + val & CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR) +- cci->master[0].status = -ENXIO; ++ cci->master[1].status = -ENXIO; + else +- cci->master[0].status = -EIO; ++ cci->master[1].status = -EIO; + + writel(CCI_HALT_REQ_I2C_M1_Q0Q1, cci->base + CCI_HALT_REQ); + ret = IRQ_HANDLED; diff --git a/queue-5.9/i2c-qup-fix-error-return-code-in-qup_i2c_bam_schedule_desc.patch b/queue-5.9/i2c-qup-fix-error-return-code-in-qup_i2c_bam_schedule_desc.patch new file mode 100644 index 00000000000..2f1447689ec --- /dev/null +++ b/queue-5.9/i2c-qup-fix-error-return-code-in-qup_i2c_bam_schedule_desc.patch @@ -0,0 +1,35 @@ +From e9acf0298c664f825e6f1158f2a97341bf9e03ca Mon Sep 17 00:00:00 2001 +From: Zhihao Cheng +Date: Mon, 16 Nov 2020 22:10:58 +0800 +Subject: i2c: qup: Fix error return code in qup_i2c_bam_schedule_desc() + +From: Zhihao Cheng + +commit e9acf0298c664f825e6f1158f2a97341bf9e03ca upstream. + +Fix to return the error code from qup_i2c_change_state() +instaed of 0 in qup_i2c_bam_schedule_desc(). + +Fixes: fbf9921f8b35d9b2 ("i2c: qup: Fix error handling") +Reported-by: Hulk Robot +Signed-off-by: Zhihao Cheng +Reviewed-by: Bjorn Andersson +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-qup.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/i2c/busses/i2c-qup.c ++++ b/drivers/i2c/busses/i2c-qup.c +@@ -801,7 +801,8 @@ static int qup_i2c_bam_schedule_desc(str + if (ret || qup->bus_err || qup->qup_err) { + reinit_completion(&qup->xfer); + +- if (qup_i2c_change_state(qup, QUP_RUN_STATE)) { ++ ret = qup_i2c_change_state(qup, QUP_RUN_STATE); ++ if (ret) { + dev_err(qup->dev, "change to run state timed out"); + goto desc_err; + } diff --git a/queue-5.9/input-i8042-fix-error-return-code-in-i8042_setup_aux.patch b/queue-5.9/input-i8042-fix-error-return-code-in-i8042_setup_aux.patch new file mode 100644 index 00000000000..803b4b5e9ff --- /dev/null +++ b/queue-5.9/input-i8042-fix-error-return-code-in-i8042_setup_aux.patch @@ -0,0 +1,37 @@ +From 855b69857830f8d918d715014f05e59a3f7491a0 Mon Sep 17 00:00:00 2001 +From: Luo Meng +Date: Tue, 24 Nov 2020 17:45:23 -0800 +Subject: Input: i8042 - fix error return code in i8042_setup_aux() + +From: Luo Meng + +commit 855b69857830f8d918d715014f05e59a3f7491a0 upstream. + +Fix to return a negative error code from the error handling case +instead of 0 in function i8042_setup_aux(), as done elsewhere in this +function. + +Fixes: f81134163fc7 ("Input: i8042 - use platform_driver_probe") +Reported-by: Hulk Robot +Signed-off-by: Luo Meng +Reviewed-by: Hans de Goede +Link: https://lore.kernel.org/r/20201123133420.4071187-1-luomeng12@huawei.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/serio/i8042.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/input/serio/i8042.c ++++ b/drivers/input/serio/i8042.c +@@ -1471,7 +1471,8 @@ static int __init i8042_setup_aux(void) + if (error) + goto err_free_ports; + +- if (aux_enable()) ++ error = aux_enable(); ++ if (error) + goto err_free_irq; + + i8042_aux_irq_registered = true; diff --git a/queue-5.9/netfilter-ipset-prevent-uninit-value-in-hash_ip6_add.patch b/queue-5.9/netfilter-ipset-prevent-uninit-value-in-hash_ip6_add.patch new file mode 100644 index 00000000000..1274827c223 --- /dev/null +++ b/queue-5.9/netfilter-ipset-prevent-uninit-value-in-hash_ip6_add.patch @@ -0,0 +1,159 @@ +From 68ad89de918e1c5a79c9c56127e5e31741fd517e Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 19 Nov 2020 01:59:32 -0800 +Subject: netfilter: ipset: prevent uninit-value in hash_ip6_add + +From: Eric Dumazet + +commit 68ad89de918e1c5a79c9c56127e5e31741fd517e upstream. + +syzbot found that we are not validating user input properly +before copying 16 bytes [1]. + +Using NLA_BINARY in ipaddr_policy[] for IPv6 address is not correct, +since it ensures at most 16 bytes were provided. + +We should instead make sure user provided exactly 16 bytes. + +In old kernels (before v4.20), fix would be to remove the NLA_BINARY, +since NLA_POLICY_EXACT_LEN() was not yet available. + +[1] +BUG: KMSAN: uninit-value in hash_ip6_add+0x1cba/0x3a50 net/netfilter/ipset/ip_set_hash_gen.h:892 +CPU: 1 PID: 11611 Comm: syz-executor.0 Not tainted 5.10.0-rc4-syzkaller #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 +Call Trace: + __dump_stack lib/dump_stack.c:77 [inline] + dump_stack+0x21c/0x280 lib/dump_stack.c:118 + kmsan_report+0xf7/0x1e0 mm/kmsan/kmsan_report.c:118 + __msan_warning+0x5f/0xa0 mm/kmsan/kmsan_instr.c:197 + hash_ip6_add+0x1cba/0x3a50 net/netfilter/ipset/ip_set_hash_gen.h:892 + hash_ip6_uadt+0x976/0xbd0 net/netfilter/ipset/ip_set_hash_ip.c:267 + call_ad+0x329/0xd00 net/netfilter/ipset/ip_set_core.c:1720 + ip_set_ad+0x111f/0x1440 net/netfilter/ipset/ip_set_core.c:1808 + ip_set_uadd+0xf6/0x110 net/netfilter/ipset/ip_set_core.c:1833 + nfnetlink_rcv_msg+0xc7d/0xdf0 net/netfilter/nfnetlink.c:252 + netlink_rcv_skb+0x70a/0x820 net/netlink/af_netlink.c:2494 + nfnetlink_rcv+0x4f0/0x4380 net/netfilter/nfnetlink.c:600 + netlink_unicast_kernel net/netlink/af_netlink.c:1304 [inline] + netlink_unicast+0x11da/0x14b0 net/netlink/af_netlink.c:1330 + netlink_sendmsg+0x173c/0x1840 net/netlink/af_netlink.c:1919 + sock_sendmsg_nosec net/socket.c:651 [inline] + sock_sendmsg net/socket.c:671 [inline] + ____sys_sendmsg+0xc7a/0x1240 net/socket.c:2353 + ___sys_sendmsg net/socket.c:2407 [inline] + __sys_sendmsg+0x6d5/0x830 net/socket.c:2440 + __do_sys_sendmsg net/socket.c:2449 [inline] + __se_sys_sendmsg+0x97/0xb0 net/socket.c:2447 + __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2447 + do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +RIP: 0033:0x45deb9 +Code: 0d b4 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 db b3 fb ff c3 66 2e 0f 1f 84 00 00 00 00 +RSP: 002b:00007fe2e503fc78 EFLAGS: 00000246 ORIG_RAX: 000000000000002e +RAX: ffffffffffffffda RBX: 0000000000029ec0 RCX: 000000000045deb9 +RDX: 0000000000000000 RSI: 0000000020000140 RDI: 0000000000000003 +RBP: 000000000118bf60 R08: 0000000000000000 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000246 R12: 000000000118bf2c +R13: 000000000169fb7f R14: 00007fe2e50409c0 R15: 000000000118bf2c + +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:121 [inline] + kmsan_internal_chain_origin+0xad/0x130 mm/kmsan/kmsan.c:289 + __msan_chain_origin+0x57/0xa0 mm/kmsan/kmsan_instr.c:147 + ip6_netmask include/linux/netfilter/ipset/pfxlen.h:49 [inline] + hash_ip6_netmask net/netfilter/ipset/ip_set_hash_ip.c:185 [inline] + hash_ip6_uadt+0xb1c/0xbd0 net/netfilter/ipset/ip_set_hash_ip.c:263 + call_ad+0x329/0xd00 net/netfilter/ipset/ip_set_core.c:1720 + ip_set_ad+0x111f/0x1440 net/netfilter/ipset/ip_set_core.c:1808 + ip_set_uadd+0xf6/0x110 net/netfilter/ipset/ip_set_core.c:1833 + nfnetlink_rcv_msg+0xc7d/0xdf0 net/netfilter/nfnetlink.c:252 + netlink_rcv_skb+0x70a/0x820 net/netlink/af_netlink.c:2494 + nfnetlink_rcv+0x4f0/0x4380 net/netfilter/nfnetlink.c:600 + netlink_unicast_kernel net/netlink/af_netlink.c:1304 [inline] + netlink_unicast+0x11da/0x14b0 net/netlink/af_netlink.c:1330 + netlink_sendmsg+0x173c/0x1840 net/netlink/af_netlink.c:1919 + sock_sendmsg_nosec net/socket.c:651 [inline] + sock_sendmsg net/socket.c:671 [inline] + ____sys_sendmsg+0xc7a/0x1240 net/socket.c:2353 + ___sys_sendmsg net/socket.c:2407 [inline] + __sys_sendmsg+0x6d5/0x830 net/socket.c:2440 + __do_sys_sendmsg net/socket.c:2449 [inline] + __se_sys_sendmsg+0x97/0xb0 net/socket.c:2447 + __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2447 + do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Uninit was stored to memory at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:121 [inline] + kmsan_internal_chain_origin+0xad/0x130 mm/kmsan/kmsan.c:289 + kmsan_memcpy_memmove_metadata+0x25e/0x2d0 mm/kmsan/kmsan.c:226 + kmsan_memcpy_metadata+0xb/0x10 mm/kmsan/kmsan.c:246 + __msan_memcpy+0x46/0x60 mm/kmsan/kmsan_instr.c:110 + ip_set_get_ipaddr6+0x2cb/0x370 net/netfilter/ipset/ip_set_core.c:310 + hash_ip6_uadt+0x439/0xbd0 net/netfilter/ipset/ip_set_hash_ip.c:255 + call_ad+0x329/0xd00 net/netfilter/ipset/ip_set_core.c:1720 + ip_set_ad+0x111f/0x1440 net/netfilter/ipset/ip_set_core.c:1808 + ip_set_uadd+0xf6/0x110 net/netfilter/ipset/ip_set_core.c:1833 + nfnetlink_rcv_msg+0xc7d/0xdf0 net/netfilter/nfnetlink.c:252 + netlink_rcv_skb+0x70a/0x820 net/netlink/af_netlink.c:2494 + nfnetlink_rcv+0x4f0/0x4380 net/netfilter/nfnetlink.c:600 + netlink_unicast_kernel net/netlink/af_netlink.c:1304 [inline] + netlink_unicast+0x11da/0x14b0 net/netlink/af_netlink.c:1330 + netlink_sendmsg+0x173c/0x1840 net/netlink/af_netlink.c:1919 + sock_sendmsg_nosec net/socket.c:651 [inline] + sock_sendmsg net/socket.c:671 [inline] + ____sys_sendmsg+0xc7a/0x1240 net/socket.c:2353 + ___sys_sendmsg net/socket.c:2407 [inline] + __sys_sendmsg+0x6d5/0x830 net/socket.c:2440 + __do_sys_sendmsg net/socket.c:2449 [inline] + __se_sys_sendmsg+0x97/0xb0 net/socket.c:2447 + __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2447 + do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Uninit was created at: + kmsan_save_stack_with_flags mm/kmsan/kmsan.c:121 [inline] + kmsan_internal_poison_shadow+0x5c/0xf0 mm/kmsan/kmsan.c:104 + kmsan_slab_alloc+0x8d/0xe0 mm/kmsan/kmsan_hooks.c:76 + slab_alloc_node mm/slub.c:2906 [inline] + __kmalloc_node_track_caller+0xc61/0x15f0 mm/slub.c:4512 + __kmalloc_reserve net/core/skbuff.c:142 [inline] + __alloc_skb+0x309/0xae0 net/core/skbuff.c:210 + alloc_skb include/linux/skbuff.h:1094 [inline] + netlink_alloc_large_skb net/netlink/af_netlink.c:1176 [inline] + netlink_sendmsg+0xdb8/0x1840 net/netlink/af_netlink.c:1894 + sock_sendmsg_nosec net/socket.c:651 [inline] + sock_sendmsg net/socket.c:671 [inline] + ____sys_sendmsg+0xc7a/0x1240 net/socket.c:2353 + ___sys_sendmsg net/socket.c:2407 [inline] + __sys_sendmsg+0x6d5/0x830 net/socket.c:2440 + __do_sys_sendmsg net/socket.c:2449 [inline] + __se_sys_sendmsg+0x97/0xb0 net/socket.c:2447 + __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2447 + do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Fixes: a7b4f989a629 ("netfilter: ipset: IP set core support") +Signed-off-by: Eric Dumazet +Reported-by: syzbot +Acked-by: Jozsef Kadlecsik +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/ipset/ip_set_core.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -286,8 +286,7 @@ flag_nested(const struct nlattr *nla) + + static const struct nla_policy ipaddr_policy[IPSET_ATTR_IPADDR_MAX + 1] = { + [IPSET_ATTR_IPADDR_IPV4] = { .type = NLA_U32 }, +- [IPSET_ATTR_IPADDR_IPV6] = { .type = NLA_BINARY, +- .len = sizeof(struct in6_addr) }, ++ [IPSET_ATTR_IPADDR_IPV6] = NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)), + }; + + int diff --git a/queue-5.9/netfilter-nf_tables-avoid-false-postive-lockdep-splat.patch b/queue-5.9/netfilter-nf_tables-avoid-false-postive-lockdep-splat.patch new file mode 100644 index 00000000000..cbcba43dccb --- /dev/null +++ b/queue-5.9/netfilter-nf_tables-avoid-false-postive-lockdep-splat.patch @@ -0,0 +1,45 @@ +From c0700dfa2cae44c033ed97dade8a2679c7d22a9d Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Thu, 19 Nov 2020 16:34:54 +0100 +Subject: netfilter: nf_tables: avoid false-postive lockdep splat + +From: Florian Westphal + +commit c0700dfa2cae44c033ed97dade8a2679c7d22a9d upstream. + +There are reports wrt lockdep splat in nftables, e.g.: +------------[ cut here ]------------ +WARNING: CPU: 2 PID: 31416 at net/netfilter/nf_tables_api.c:622 +lockdep_nfnl_nft_mutex_not_held+0x28/0x38 [nf_tables] +... + +These are caused by an earlier, unrelated bug such as a n ABBA deadlock +in a different subsystem. +In such an event, lockdep is disabled and lockdep_is_held returns true +unconditionally. This then causes the WARN() in nf_tables. + +Make the WARN conditional on lockdep still active to avoid this. + +Fixes: f102d66b335a417 ("netfilter: nf_tables: use dedicated mutex to guard transactions") +Reported-by: Naresh Kamboju +Link: https://lore.kernel.org/linux-kselftest/CA+G9fYvFUpODs+NkSYcnwKnXm62tmP=ksLeBPmB+KFrB2rvCtQ@mail.gmail.com/ +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_tables_api.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -619,7 +619,8 @@ static int nft_request_module(struct net + static void lockdep_nfnl_nft_mutex_not_held(void) + { + #ifdef CONFIG_PROVE_LOCKING +- WARN_ON_ONCE(lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES)); ++ if (debug_locks) ++ WARN_ON_ONCE(lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES)); + #endif + } + diff --git a/queue-5.9/netfilter-nftables_offload-build-mask-based-from-the-matching-bytes.patch b/queue-5.9/netfilter-nftables_offload-build-mask-based-from-the-matching-bytes.patch new file mode 100644 index 00000000000..ac868f80cea --- /dev/null +++ b/queue-5.9/netfilter-nftables_offload-build-mask-based-from-the-matching-bytes.patch @@ -0,0 +1,290 @@ +From a5d45bc0dc50f9dd83703510e9804d813a9cac32 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Wed, 25 Nov 2020 23:50:17 +0100 +Subject: netfilter: nftables_offload: build mask based from the matching bytes + +From: Pablo Neira Ayuso + +commit a5d45bc0dc50f9dd83703510e9804d813a9cac32 upstream. + +Userspace might match on prefix bytes of header fields if they are on +the byte boundary, this requires that the mask is adjusted accordingly. +Use NFT_OFFLOAD_MATCH_EXACT() for meta since prefix byte matching is not +allowed for this type of selector. + +The bitwise expression might be optimized out by userspace, hence the +kernel needs to infer the prefix from the number of payload bytes to +match on. This patch adds nft_payload_offload_mask() to calculate the +bitmask to match on the prefix. + +Fixes: c9626a2cbdb2 ("netfilter: nf_tables: add hardware offload support") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/netfilter/nf_tables_offload.h | 3 + + net/netfilter/nft_cmp.c | 8 +-- + net/netfilter/nft_meta.c | 16 +++---- + net/netfilter/nft_payload.c | 66 ++++++++++++++++++++++-------- + 4 files changed, 64 insertions(+), 29 deletions(-) + +--- a/include/net/netfilter/nf_tables_offload.h ++++ b/include/net/netfilter/nf_tables_offload.h +@@ -78,6 +78,9 @@ int nft_flow_rule_offload_commit(struct + offsetof(struct nft_flow_key, __base.__field); \ + (__reg)->len = __len; \ + (__reg)->key = __key; \ ++ ++#define NFT_OFFLOAD_MATCH_EXACT(__key, __base, __field, __len, __reg) \ ++ NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \ + memset(&(__reg)->mask, 0xff, (__reg)->len); + + int nft_chain_offload_priority(struct nft_base_chain *basechain); +--- a/net/netfilter/nft_cmp.c ++++ b/net/netfilter/nft_cmp.c +@@ -123,11 +123,11 @@ static int __nft_cmp_offload(struct nft_ + u8 *mask = (u8 *)&flow->match.mask; + u8 *key = (u8 *)&flow->match.key; + +- if (priv->op != NFT_CMP_EQ || reg->len != priv->len) ++ if (priv->op != NFT_CMP_EQ || priv->len > reg->len) + return -EOPNOTSUPP; + +- memcpy(key + reg->offset, &priv->data, priv->len); +- memcpy(mask + reg->offset, ®->mask, priv->len); ++ memcpy(key + reg->offset, &priv->data, reg->len); ++ memcpy(mask + reg->offset, ®->mask, reg->len); + + flow->match.dissector.used_keys |= BIT(reg->key); + flow->match.dissector.offset[reg->key] = reg->base_offset; +@@ -137,7 +137,7 @@ static int __nft_cmp_offload(struct nft_ + nft_reg_load16(priv->data.data) != ARPHRD_ETHER) + return -EOPNOTSUPP; + +- nft_offload_update_dependency(ctx, &priv->data, priv->len); ++ nft_offload_update_dependency(ctx, &priv->data, reg->len); + + return 0; + } +--- a/net/netfilter/nft_meta.c ++++ b/net/netfilter/nft_meta.c +@@ -724,22 +724,22 @@ static int nft_meta_get_offload(struct n + + switch (priv->key) { + case NFT_META_PROTOCOL: +- NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, n_proto, +- sizeof(__u16), reg); ++ NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC, basic, n_proto, ++ sizeof(__u16), reg); + nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK); + break; + case NFT_META_L4PROTO: +- NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, +- sizeof(__u8), reg); ++ NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, ++ sizeof(__u8), reg); + nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT); + break; + case NFT_META_IIF: +- NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_META, meta, +- ingress_ifindex, sizeof(__u32), reg); ++ NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META, meta, ++ ingress_ifindex, sizeof(__u32), reg); + break; + case NFT_META_IIFTYPE: +- NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_META, meta, +- ingress_iftype, sizeof(__u16), reg); ++ NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META, meta, ++ ingress_iftype, sizeof(__u16), reg); + break; + default: + return -EOPNOTSUPP; +--- a/net/netfilter/nft_payload.c ++++ b/net/netfilter/nft_payload.c +@@ -164,6 +164,34 @@ nla_put_failure: + return -1; + } + ++static bool nft_payload_offload_mask(struct nft_offload_reg *reg, ++ u32 priv_len, u32 field_len) ++{ ++ unsigned int remainder, delta, k; ++ struct nft_data mask = {}; ++ __be32 remainder_mask; ++ ++ if (priv_len == field_len) { ++ memset(®->mask, 0xff, priv_len); ++ return true; ++ } else if (priv_len > field_len) { ++ return false; ++ } ++ ++ memset(&mask, 0xff, field_len); ++ remainder = priv_len % sizeof(u32); ++ if (remainder) { ++ k = priv_len / sizeof(u32); ++ delta = field_len - priv_len; ++ remainder_mask = htonl(~((1 << (delta * BITS_PER_BYTE)) - 1)); ++ mask.data[k] = (__force u32)remainder_mask; ++ } ++ ++ memcpy(®->mask, &mask, field_len); ++ ++ return true; ++} ++ + static int nft_payload_offload_ll(struct nft_offload_ctx *ctx, + struct nft_flow_rule *flow, + const struct nft_payload *priv) +@@ -172,21 +200,21 @@ static int nft_payload_offload_ll(struct + + switch (priv->offset) { + case offsetof(struct ethhdr, h_source): +- if (priv->len != ETH_ALEN) ++ if (!nft_payload_offload_mask(reg, priv->len, ETH_ALEN)) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs, + src, ETH_ALEN, reg); + break; + case offsetof(struct ethhdr, h_dest): +- if (priv->len != ETH_ALEN) ++ if (!nft_payload_offload_mask(reg, priv->len, ETH_ALEN)) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_ETH_ADDRS, eth_addrs, + dst, ETH_ALEN, reg); + break; + case offsetof(struct ethhdr, h_proto): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, +@@ -194,14 +222,14 @@ static int nft_payload_offload_ll(struct + nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK); + break; + case offsetof(struct vlan_ethhdr, h_vlan_TCI): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan, + vlan_tci, sizeof(__be16), reg); + break; + case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_VLAN, vlan, +@@ -209,7 +237,7 @@ static int nft_payload_offload_ll(struct + nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK); + break; + case offsetof(struct vlan_ethhdr, h_vlan_TCI) + sizeof(struct vlan_hdr): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, vlan, +@@ -217,7 +245,7 @@ static int nft_payload_offload_ll(struct + break; + case offsetof(struct vlan_ethhdr, h_vlan_encapsulated_proto) + + sizeof(struct vlan_hdr): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_CVLAN, vlan, +@@ -238,7 +266,8 @@ static int nft_payload_offload_ip(struct + + switch (priv->offset) { + case offsetof(struct iphdr, saddr): +- if (priv->len != sizeof(struct in_addr)) ++ if (!nft_payload_offload_mask(reg, priv->len, ++ sizeof(struct in_addr))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src, +@@ -246,7 +275,8 @@ static int nft_payload_offload_ip(struct + nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV4_ADDRS); + break; + case offsetof(struct iphdr, daddr): +- if (priv->len != sizeof(struct in_addr)) ++ if (!nft_payload_offload_mask(reg, priv->len, ++ sizeof(struct in_addr))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst, +@@ -254,7 +284,7 @@ static int nft_payload_offload_ip(struct + nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV4_ADDRS); + break; + case offsetof(struct iphdr, protocol): +- if (priv->len != sizeof(__u8)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__u8))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, +@@ -276,7 +306,8 @@ static int nft_payload_offload_ip6(struc + + switch (priv->offset) { + case offsetof(struct ipv6hdr, saddr): +- if (priv->len != sizeof(struct in6_addr)) ++ if (!nft_payload_offload_mask(reg, priv->len, ++ sizeof(struct in6_addr))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src, +@@ -284,7 +315,8 @@ static int nft_payload_offload_ip6(struc + nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV6_ADDRS); + break; + case offsetof(struct ipv6hdr, daddr): +- if (priv->len != sizeof(struct in6_addr)) ++ if (!nft_payload_offload_mask(reg, priv->len, ++ sizeof(struct in6_addr))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst, +@@ -292,7 +324,7 @@ static int nft_payload_offload_ip6(struc + nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV6_ADDRS); + break; + case offsetof(struct ipv6hdr, nexthdr): +- if (priv->len != sizeof(__u8)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__u8))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto, +@@ -334,14 +366,14 @@ static int nft_payload_offload_tcp(struc + + switch (priv->offset) { + case offsetof(struct tcphdr, source): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src, + sizeof(__be16), reg); + break; + case offsetof(struct tcphdr, dest): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst, +@@ -362,14 +394,14 @@ static int nft_payload_offload_udp(struc + + switch (priv->offset) { + case offsetof(struct udphdr, source): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, src, + sizeof(__be16), reg); + break; + case offsetof(struct udphdr, dest): +- if (priv->len != sizeof(__be16)) ++ if (!nft_payload_offload_mask(reg, priv->len, sizeof(__be16))) + return -EOPNOTSUPP; + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_PORTS, tp, dst, diff --git a/queue-5.9/netfilter-nftables_offload-set-address-type-in-control-dissector.patch b/queue-5.9/netfilter-nftables_offload-set-address-type-in-control-dissector.patch new file mode 100644 index 00000000000..f01ff108150 --- /dev/null +++ b/queue-5.9/netfilter-nftables_offload-set-address-type-in-control-dissector.patch @@ -0,0 +1,114 @@ +From 3c78e9e0d33a27ab8050e4492c03c6a1f8d0ed6b Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Wed, 25 Nov 2020 23:50:07 +0100 +Subject: netfilter: nftables_offload: set address type in control dissector + +From: Pablo Neira Ayuso + +commit 3c78e9e0d33a27ab8050e4492c03c6a1f8d0ed6b upstream. + +This patch adds nft_flow_rule_set_addr_type() to set the address type +from the nft_payload expression accordingly. + +If the address type is not set in the control dissector then a rule that +matches either on source or destination IP address does not work. + +After this patch, nft hardware offload generates the flow dissector +configuration as tc-flower does to match on an IP address. + +This patch has been also tested functionally to make sure packets are +filtered out by the NIC. + +This is also getting the code aligned with the existing netfilter flow +offload infrastructure which is also setting the control dissector. + +Fixes: c9626a2cbdb2 ("netfilter: nf_tables: add hardware offload support") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/netfilter/nf_tables_offload.h | 4 ++++ + net/netfilter/nf_tables_offload.c | 17 +++++++++++++++++ + net/netfilter/nft_payload.c | 4 ++++ + 3 files changed, 25 insertions(+) + +--- a/include/net/netfilter/nf_tables_offload.h ++++ b/include/net/netfilter/nf_tables_offload.h +@@ -37,6 +37,7 @@ void nft_offload_update_dependency(struc + + struct nft_flow_key { + struct flow_dissector_key_basic basic; ++ struct flow_dissector_key_control control; + union { + struct flow_dissector_key_ipv4_addrs ipv4; + struct flow_dissector_key_ipv6_addrs ipv6; +@@ -62,6 +63,9 @@ struct nft_flow_rule { + + #define NFT_OFFLOAD_F_ACTION (1 << 0) + ++void nft_flow_rule_set_addr_type(struct nft_flow_rule *flow, ++ enum flow_dissector_key_id addr_type); ++ + struct nft_rule; + struct nft_flow_rule *nft_flow_rule_create(struct net *net, const struct nft_rule *rule); + void nft_flow_rule_destroy(struct nft_flow_rule *flow); +--- a/net/netfilter/nf_tables_offload.c ++++ b/net/netfilter/nf_tables_offload.c +@@ -28,6 +28,23 @@ static struct nft_flow_rule *nft_flow_ru + return flow; + } + ++void nft_flow_rule_set_addr_type(struct nft_flow_rule *flow, ++ enum flow_dissector_key_id addr_type) ++{ ++ struct nft_flow_match *match = &flow->match; ++ struct nft_flow_key *mask = &match->mask; ++ struct nft_flow_key *key = &match->key; ++ ++ if (match->dissector.used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) ++ return; ++ ++ key->control.addr_type = addr_type; ++ mask->control.addr_type = 0xffff; ++ match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_CONTROL); ++ match->dissector.offset[FLOW_DISSECTOR_KEY_CONTROL] = ++ offsetof(struct nft_flow_key, control); ++} ++ + struct nft_flow_rule *nft_flow_rule_create(struct net *net, + const struct nft_rule *rule) + { +--- a/net/netfilter/nft_payload.c ++++ b/net/netfilter/nft_payload.c +@@ -243,6 +243,7 @@ static int nft_payload_offload_ip(struct + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, src, + sizeof(struct in_addr), reg); ++ nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV4_ADDRS); + break; + case offsetof(struct iphdr, daddr): + if (priv->len != sizeof(struct in_addr)) +@@ -250,6 +251,7 @@ static int nft_payload_offload_ip(struct + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4, dst, + sizeof(struct in_addr), reg); ++ nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV4_ADDRS); + break; + case offsetof(struct iphdr, protocol): + if (priv->len != sizeof(__u8)) +@@ -279,6 +281,7 @@ static int nft_payload_offload_ip6(struc + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, src, + sizeof(struct in6_addr), reg); ++ nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV6_ADDRS); + break; + case offsetof(struct ipv6hdr, daddr): + if (priv->len != sizeof(struct in6_addr)) +@@ -286,6 +289,7 @@ static int nft_payload_offload_ip6(struc + + NFT_OFFLOAD_MATCH(FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6, dst, + sizeof(struct in6_addr), reg); ++ nft_flow_rule_set_addr_type(flow, FLOW_DISSECTOR_KEY_IPV6_ADDRS); + break; + case offsetof(struct ipv6hdr, nexthdr): + if (priv->len != sizeof(__u8)) diff --git a/queue-5.9/rtw88-debug-fix-uninitialized-memory-in-debugfs-code.patch b/queue-5.9/rtw88-debug-fix-uninitialized-memory-in-debugfs-code.patch new file mode 100644 index 00000000000..0be51b9ca68 --- /dev/null +++ b/queue-5.9/rtw88-debug-fix-uninitialized-memory-in-debugfs-code.patch @@ -0,0 +1,34 @@ +From 74a8c816fa8fa7862df870660e9821abb56649fe Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 3 Dec 2020 11:43:37 +0300 +Subject: rtw88: debug: Fix uninitialized memory in debugfs code + +From: Dan Carpenter + +commit 74a8c816fa8fa7862df870660e9821abb56649fe upstream. + +This code does not ensure that the whole buffer is initialized and none +of the callers check for errors so potentially none of the buffer is +initialized. Add a memset to eliminate this bug. + +Fixes: e3037485c68e ("rtw88: new Realtek 802.11ac driver") +Signed-off-by: Dan Carpenter +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/X8ilOfVz3pf0T5ec@mwanda +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/realtek/rtw88/debug.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/debug.c ++++ b/drivers/net/wireless/realtek/rtw88/debug.c +@@ -147,6 +147,8 @@ static int rtw_debugfs_copy_from_user(ch + { + int tmp_len; + ++ memset(tmp, 0, size); ++ + if (count < num) + return -EFAULT; + diff --git a/queue-5.9/series b/queue-5.9/series index ff34f7386b7..7f9ff3d19fd 100644 --- a/queue-5.9/series +++ b/queue-5.9/series @@ -57,3 +57,18 @@ revert-amd-amdgpu-disable-vcn-dpg-mode-for-picasso.patch iommu-amd-set-dte-to-represent-512-irtes.patch mm-memcg-slab-fix-obj_cgroup_charge-return-value-handling.patch lib-syscall-fix-syscall-registers-retrieval-on-32-bit-platforms.patch +can-af_can-can_rx_unregister-remove-warn-statement-from-list-operation-sanity-check.patch +gfs2-check-for-empty-rgrp-tree-in-gfs2_ri_update.patch +netfilter-ipset-prevent-uninit-value-in-hash_ip6_add.patch +tipc-fix-a-deadlock-when-flushing-scheduled-work.patch +asoc-wm_adsp-fix-error-return-code-in-wm_adsp_load.patch +gfs2-fix-deadlock-dumping-resource-group-glocks.patch +gfs2-don-t-freeze-the-file-system-during-unmount.patch +rtw88-debug-fix-uninitialized-memory-in-debugfs-code.patch +i2c-qcom-fix-irq-error-misassignement.patch +i2c-qup-fix-error-return-code-in-qup_i2c_bam_schedule_desc.patch +dm-writecache-remove-bug-and-fail-gracefully-instead.patch +input-i8042-fix-error-return-code-in-i8042_setup_aux.patch +netfilter-nf_tables-avoid-false-postive-lockdep-splat.patch +netfilter-nftables_offload-set-address-type-in-control-dissector.patch +netfilter-nftables_offload-build-mask-based-from-the-matching-bytes.patch diff --git a/queue-5.9/tipc-fix-a-deadlock-when-flushing-scheduled-work.patch b/queue-5.9/tipc-fix-a-deadlock-when-flushing-scheduled-work.patch new file mode 100644 index 00000000000..a7abcc687e8 --- /dev/null +++ b/queue-5.9/tipc-fix-a-deadlock-when-flushing-scheduled-work.patch @@ -0,0 +1,171 @@ +From d966ddcc38217a6110a6a0ff37ad2dee7d42e23e Mon Sep 17 00:00:00 2001 +From: Hoang Huu Le +Date: Mon, 7 Sep 2020 13:17:25 +0700 +Subject: tipc: fix a deadlock when flushing scheduled work + +From: Hoang Huu Le + +commit d966ddcc38217a6110a6a0ff37ad2dee7d42e23e upstream. + +In the commit fdeba99b1e58 +("tipc: fix use-after-free in tipc_bcast_get_mode"), we're trying +to make sure the tipc_net_finalize_work work item finished if it +enqueued. But calling flush_scheduled_work() is not just affecting +above work item but either any scheduled work. This has turned out +to be overkill and caused to deadlock as syzbot reported: + +====================================================== +WARNING: possible circular locking dependency detected +5.9.0-rc2-next-20200828-syzkaller #0 Not tainted +------------------------------------------------------ +kworker/u4:6/349 is trying to acquire lock: +ffff8880aa063d38 ((wq_completion)events){+.+.}-{0:0}, at: flush_workqueue+0xe1/0x13e0 kernel/workqueue.c:2777 + +but task is already holding lock: +ffffffff8a879430 (pernet_ops_rwsem){++++}-{3:3}, at: cleanup_net+0x9b/0xb10 net/core/net_namespace.c:565 + +[...] + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(pernet_ops_rwsem); + lock(&sb->s_type->i_mutex_key#13); + lock(pernet_ops_rwsem); + lock((wq_completion)events); + + *** DEADLOCK *** +[...] + +v1: +To fix the original issue, we replace above calling by introducing +a bit flag. When a namespace cleaned-up, bit flag is set to zero and: +- tipc_net_finalize functionial just does return immediately. +- tipc_net_finalize_work does not enqueue into the scheduled work queue. + +v2: +Use cancel_work_sync() helper to make sure ONLY the +tipc_net_finalize_work() stopped before releasing bcbase object. + +Reported-by: syzbot+d5aa7e0385f6a5d0f4fd@syzkaller.appspotmail.com +Fixes: fdeba99b1e58 ("tipc: fix use-after-free in tipc_bcast_get_mode") +Acked-by: Jon Maloy +Signed-off-by: Hoang Huu Le +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman + +--- + net/tipc/core.c | 9 +++++---- + net/tipc/core.h | 8 ++++++++ + net/tipc/net.c | 20 +++++--------------- + net/tipc/net.h | 1 + + 4 files changed, 19 insertions(+), 19 deletions(-) + +--- a/net/tipc/core.c ++++ b/net/tipc/core.c +@@ -60,6 +60,7 @@ static int __net_init tipc_init_net(stru + tn->trial_addr = 0; + tn->addr_trial_end = 0; + tn->capabilities = TIPC_NODE_CAPABILITIES; ++ INIT_WORK(&tn->final_work.work, tipc_net_finalize_work); + memset(tn->node_id, 0, sizeof(tn->node_id)); + memset(tn->node_id_string, 0, sizeof(tn->node_id_string)); + tn->mon_threshold = TIPC_DEF_MON_THRESHOLD; +@@ -107,13 +108,13 @@ out_crypto: + + static void __net_exit tipc_exit_net(struct net *net) + { ++ struct tipc_net *tn = tipc_net(net); ++ + tipc_detach_loopback(net); ++ /* Make sure the tipc_net_finalize_work() finished */ ++ cancel_work_sync(&tn->final_work.work); + tipc_net_stop(net); + +- /* Make sure the tipc_net_finalize_work stopped +- * before releasing the resources. +- */ +- flush_scheduled_work(); + tipc_bcast_stop(net); + tipc_nametbl_stop(net); + tipc_sk_rht_destroy(net); +--- a/net/tipc/core.h ++++ b/net/tipc/core.h +@@ -90,6 +90,12 @@ extern unsigned int tipc_net_id __read_m + extern int sysctl_tipc_rmem[3] __read_mostly; + extern int sysctl_tipc_named_timeout __read_mostly; + ++struct tipc_net_work { ++ struct work_struct work; ++ struct net *net; ++ u32 addr; ++}; ++ + struct tipc_net { + u8 node_id[NODE_ID_LEN]; + u32 node_addr; +@@ -143,6 +149,8 @@ struct tipc_net { + /* TX crypto handler */ + struct tipc_crypto *crypto_tx; + #endif ++ /* Work item for net finalize */ ++ struct tipc_net_work final_work; + }; + + static inline struct tipc_net *tipc_net(struct net *net) +--- a/net/tipc/net.c ++++ b/net/tipc/net.c +@@ -105,12 +105,6 @@ + * - A local spin_lock protecting the queue of subscriber events. + */ + +-struct tipc_net_work { +- struct work_struct work; +- struct net *net; +- u32 addr; +-}; +- + static void tipc_net_finalize(struct net *net, u32 addr); + + int tipc_net_init(struct net *net, u8 *node_id, u32 addr) +@@ -142,25 +136,21 @@ static void tipc_net_finalize(struct net + TIPC_CLUSTER_SCOPE, 0, addr); + } + +-static void tipc_net_finalize_work(struct work_struct *work) ++void tipc_net_finalize_work(struct work_struct *work) + { + struct tipc_net_work *fwork; + + fwork = container_of(work, struct tipc_net_work, work); + tipc_net_finalize(fwork->net, fwork->addr); +- kfree(fwork); + } + + void tipc_sched_net_finalize(struct net *net, u32 addr) + { +- struct tipc_net_work *fwork = kzalloc(sizeof(*fwork), GFP_ATOMIC); ++ struct tipc_net *tn = tipc_net(net); + +- if (!fwork) +- return; +- INIT_WORK(&fwork->work, tipc_net_finalize_work); +- fwork->net = net; +- fwork->addr = addr; +- schedule_work(&fwork->work); ++ tn->final_work.net = net; ++ tn->final_work.addr = addr; ++ schedule_work(&tn->final_work.work); + } + + void tipc_net_stop(struct net *net) +--- a/net/tipc/net.h ++++ b/net/tipc/net.h +@@ -42,6 +42,7 @@ + extern const struct nla_policy tipc_nl_net_policy[]; + + int tipc_net_init(struct net *net, u8 *node_id, u32 addr); ++void tipc_net_finalize_work(struct work_struct *work); + void tipc_sched_net_finalize(struct net *net, u32 addr); + void tipc_net_stop(struct net *net); + int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb); -- 2.47.3