]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Jun 2021 12:31:52 +0000 (14:31 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Jun 2021 12:31:52 +0000 (14:31 +0200)
added patches:
alsa-hda-fix-for-mute-key-led-for-hp-pavilion-15-ck0xx.patch
alsa-hda-update-the-power_state-during-the-direct-complete.patch
alsa-timer-fix-master-timer-notification.patch
arm-dts-imx6dl-yapp4-fix-rgmii-connection-to-qca8334-switch.patch
arm-dts-imx6q-dhcom-add-pu-vdd1p1-vdd2p5-regulators.patch
ext4-fix-accessing-uninit-percpu-counter-variable-with-fast_commit.patch
ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_split_extent_at-failed.patch
ext4-fix-fast-commit-alignment-issues.patch
ext4-fix-memory-leak-in-ext4_fill_super.patch
ext4-fix-memory-leak-in-ext4_mb_init_backend-on-error-path.patch
gfs2-fix-scheduling-while-atomic-bug-in-glocks.patch
hid-i2c-hid-skip-elan-power-on-command-after-reset.patch
hid-magicmouse-fix-null-deref-on-disconnect.patch
hid-multitouch-require-finger-field-to-mark-win8-reports-as-mt.patch
net-caif-add-proper-error-handling.patch
net-caif-added-cfserl_release-function.patch
net-caif-fix-memory-leak-in-caif_device_notify.patch
net-caif-fix-memory-leak-in-cfusbl_device_notify.patch
net-kcm-fix-memory-leak-in-kcm_sendmsg.patch

20 files changed:
queue-5.10/alsa-hda-fix-for-mute-key-led-for-hp-pavilion-15-ck0xx.patch [new file with mode: 0644]
queue-5.10/alsa-hda-update-the-power_state-during-the-direct-complete.patch [new file with mode: 0644]
queue-5.10/alsa-timer-fix-master-timer-notification.patch [new file with mode: 0644]
queue-5.10/arm-dts-imx6dl-yapp4-fix-rgmii-connection-to-qca8334-switch.patch [new file with mode: 0644]
queue-5.10/arm-dts-imx6q-dhcom-add-pu-vdd1p1-vdd2p5-regulators.patch [new file with mode: 0644]
queue-5.10/ext4-fix-accessing-uninit-percpu-counter-variable-with-fast_commit.patch [new file with mode: 0644]
queue-5.10/ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_split_extent_at-failed.patch [new file with mode: 0644]
queue-5.10/ext4-fix-fast-commit-alignment-issues.patch [new file with mode: 0644]
queue-5.10/ext4-fix-memory-leak-in-ext4_fill_super.patch [new file with mode: 0644]
queue-5.10/ext4-fix-memory-leak-in-ext4_mb_init_backend-on-error-path.patch [new file with mode: 0644]
queue-5.10/gfs2-fix-scheduling-while-atomic-bug-in-glocks.patch [new file with mode: 0644]
queue-5.10/hid-i2c-hid-skip-elan-power-on-command-after-reset.patch [new file with mode: 0644]
queue-5.10/hid-magicmouse-fix-null-deref-on-disconnect.patch [new file with mode: 0644]
queue-5.10/hid-multitouch-require-finger-field-to-mark-win8-reports-as-mt.patch [new file with mode: 0644]
queue-5.10/net-caif-add-proper-error-handling.patch [new file with mode: 0644]
queue-5.10/net-caif-added-cfserl_release-function.patch [new file with mode: 0644]
queue-5.10/net-caif-fix-memory-leak-in-caif_device_notify.patch [new file with mode: 0644]
queue-5.10/net-caif-fix-memory-leak-in-cfusbl_device_notify.patch [new file with mode: 0644]
queue-5.10/net-kcm-fix-memory-leak-in-kcm_sendmsg.patch [new file with mode: 0644]
queue-5.10/series

diff --git a/queue-5.10/alsa-hda-fix-for-mute-key-led-for-hp-pavilion-15-ck0xx.patch b/queue-5.10/alsa-hda-fix-for-mute-key-led-for-hp-pavilion-15-ck0xx.patch
new file mode 100644 (file)
index 0000000..5b6500f
--- /dev/null
@@ -0,0 +1,32 @@
+From 901be145a46eb79879367d853194346a549e623d Mon Sep 17 00:00:00 2001
+From: Carlos M <carlos.marr.pz@gmail.com>
+Date: Mon, 31 May 2021 22:20:26 +0200
+Subject: ALSA: hda: Fix for mute key LED for HP Pavilion 15-CK0xx
+
+From: Carlos M <carlos.marr.pz@gmail.com>
+
+commit 901be145a46eb79879367d853194346a549e623d upstream.
+
+For the HP Pavilion 15-CK0xx, with audio subsystem ID 0x103c:0x841c,
+adding a line in patch_realtek.c to apply the ALC269_FIXUP_HP_MUTE_LED_MIC3
+fix activates the mute key LED.
+
+Signed-off-by: Carlos M <carlos.marr.pz@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20210531202026.35427-1-carlos.marr.pz@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -8289,6 +8289,7 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x103c, 0x82bf, "HP G3 mini", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
++      SND_PCI_QUIRK(0x103c, 0x841c, "HP Pavilion 15-CK0xx", ALC269_FIXUP_HP_MUTE_LED_MIC3),
+       SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
+       SND_PCI_QUIRK(0x103c, 0x84da, "HP OMEN dc0019-ur", ALC295_FIXUP_HP_OMEN),
+       SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
diff --git a/queue-5.10/alsa-hda-update-the-power_state-during-the-direct-complete.patch b/queue-5.10/alsa-hda-update-the-power_state-during-the-direct-complete.patch
new file mode 100644 (file)
index 0000000..05b6890
--- /dev/null
@@ -0,0 +1,55 @@
+From b8b90c17602689eeaa5b219d104bbc215d1225cc Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Wed, 2 Jun 2021 22:54:24 +0800
+Subject: ALSA: hda: update the power_state during the direct-complete
+
+From: Hui Wang <hui.wang@canonical.com>
+
+commit b8b90c17602689eeaa5b219d104bbc215d1225cc upstream.
+
+The patch_realtek.c needs to check if the power_state.event equals
+PM_EVENT_SUSPEND, after using the direct-complete, the suspend() and
+resume() will be skipped if the codec is already rt_suspended, in this
+case, the patch_realtek.c will always get PM_EVENT_ON even the system
+is really resumed from S3.
+
+We could set power_state to PMSG_SUSPEND in the prepare(), if other
+PM functions are called before complete(), those functions will
+override power_state; if no other PM functions are called before
+complete(), we could know the suspend() and resume() are skipped since
+only S3 pm functions could be skipped by direct-complete, in this case
+set power_state to PMSG_RESUME in the complete(). This could guarantee
+the first time of calling hda_codec_runtime_resume() after complete()
+has the correct power_state.
+
+Fixes: 215a22ed31a1 ("ALSA: hda: Refactor codec PM to use direct-complete optimization")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Link: https://lore.kernel.org/r/20210602145424.3132-1-hui.wang@canonical.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/hda_codec.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/sound/pci/hda/hda_codec.c
++++ b/sound/pci/hda/hda_codec.c
+@@ -2973,6 +2973,7 @@ static int hda_codec_runtime_resume(stru
+ #ifdef CONFIG_PM_SLEEP
+ static int hda_codec_pm_prepare(struct device *dev)
+ {
++      dev->power.power_state = PMSG_SUSPEND;
+       return pm_runtime_suspended(dev);
+ }
+@@ -2980,6 +2981,10 @@ static void hda_codec_pm_complete(struct
+ {
+       struct hda_codec *codec = dev_to_hda_codec(dev);
++      /* If no other pm-functions are called between prepare() and complete() */
++      if (dev->power.power_state.event == PM_EVENT_SUSPEND)
++              dev->power.power_state = PMSG_RESUME;
++
+       if (pm_runtime_suspended(dev) && (codec->jackpoll_interval ||
+           hda_codec_need_resume(codec) || codec->forced_resume))
+               pm_request_resume(dev);
diff --git a/queue-5.10/alsa-timer-fix-master-timer-notification.patch b/queue-5.10/alsa-timer-fix-master-timer-notification.patch
new file mode 100644 (file)
index 0000000..0b4deb2
--- /dev/null
@@ -0,0 +1,39 @@
+From 9c1fe96bded935369f8340c2ac2e9e189f697d5d Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 2 Jun 2021 13:38:23 +0200
+Subject: ALSA: timer: Fix master timer notification
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 9c1fe96bded935369f8340c2ac2e9e189f697d5d upstream.
+
+snd_timer_notify1() calls the notification to each slave for a master
+event, but it passes a wrong event number.  It should be +10 offset,
+corresponding to SNDRV_TIMER_EVENT_MXXX, but it's incorrectly with
++100 offset.  Casually this was spotted by UBSAN check via syzkaller.
+
+Reported-by: syzbot+d102fa5b35335a7e544e@syzkaller.appspotmail.com
+Reviewed-by: Jaroslav Kysela <perex@perex.cz>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/000000000000e5560e05c3bd1d63@google.com
+Link: https://lore.kernel.org/r/20210602113823.23777-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/timer.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -520,9 +520,10 @@ static void snd_timer_notify1(struct snd
+               return;
+       if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
+               return;
++      event += 10; /* convert to SNDRV_TIMER_EVENT_MXXX */
+       list_for_each_entry(ts, &ti->slave_active_head, active_list)
+               if (ts->ccallback)
+-                      ts->ccallback(ts, event + 100, &tstamp, resolution);
++                      ts->ccallback(ts, event, &tstamp, resolution);
+ }
+ /* start/continue a master timer */
diff --git a/queue-5.10/arm-dts-imx6dl-yapp4-fix-rgmii-connection-to-qca8334-switch.patch b/queue-5.10/arm-dts-imx6dl-yapp4-fix-rgmii-connection-to-qca8334-switch.patch
new file mode 100644 (file)
index 0000000..03bf430
--- /dev/null
@@ -0,0 +1,47 @@
+From 0e4a4a08cd78efcaddbc2e4c5ed86b5a5cb8a15e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Vok=C3=A1=C4=8D?= <michal.vokac@ysoft.com>
+Date: Tue, 13 Apr 2021 16:45:57 +0200
+Subject: ARM: dts: imx6dl-yapp4: Fix RGMII connection to QCA8334 switch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Vokáč <michal.vokac@ysoft.com>
+
+commit 0e4a4a08cd78efcaddbc2e4c5ed86b5a5cb8a15e upstream.
+
+The FEC does not have a PHY so it should not have a phy-handle. It is
+connected to the switch at RGMII level so we need a fixed-link sub-node
+on both ends.
+
+This was not a problem until the qca8k.c driver was converted to PHYLINK
+by commit b3591c2a3661 ("net: dsa: qca8k: Switch to PHYLINK instead of
+PHYLIB"). That commit revealed the FEC configuration was not correct.
+
+Fixes: 87489ec3a77f ("ARM: dts: imx: Add Y Soft IOTA Draco, Hydra and Ursa boards")
+Cc: stable@vger.kernel.org
+Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/boot/dts/imx6dl-yapp4-common.dtsi |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
++++ b/arch/arm/boot/dts/imx6dl-yapp4-common.dtsi
+@@ -105,9 +105,13 @@
+       phy-reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+       phy-reset-duration = <20>;
+       phy-supply = <&sw2_reg>;
+-      phy-handle = <&ethphy0>;
+       status = "okay";
++      fixed-link {
++              speed = <1000>;
++              full-duplex;
++      };
++
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
diff --git a/queue-5.10/arm-dts-imx6q-dhcom-add-pu-vdd1p1-vdd2p5-regulators.patch b/queue-5.10/arm-dts-imx6q-dhcom-add-pu-vdd1p1-vdd2p5-regulators.patch
new file mode 100644 (file)
index 0000000..d978af2
--- /dev/null
@@ -0,0 +1,54 @@
+From 8967b27a6c1c19251989c7ab33c058d16e4a5f53 Mon Sep 17 00:00:00 2001
+From: Marek Vasut <marex@denx.de>
+Date: Mon, 26 Apr 2021 12:23:21 +0200
+Subject: ARM: dts: imx6q-dhcom: Add PU,VDD1P1,VDD2P5 regulators
+
+From: Marek Vasut <marex@denx.de>
+
+commit 8967b27a6c1c19251989c7ab33c058d16e4a5f53 upstream.
+
+Per schematic, both PU and SOC regulator are supplied from LTC3676 SW1
+via VDDSOC_IN rail, add the PU input. Both VDD1P1, VDD2P5 are supplied
+from LTC3676 SW2 via VDDHIGH_IN rail, add both inputs.
+
+While no instability or problems are currently observed, the regulators
+should be fully described in DT and that description should fully match
+the hardware, else this might lead to unforseen issues later. Fix this.
+
+Fixes: 52c7a088badd ("ARM: dts: imx6q: Add support for the DHCOM iMX6 SoM and PDK2")
+Reviewed-by: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Marek Vasut <marex@denx.de>
+Cc: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Cc: Fabio Estevam <festevam@gmail.com>
+Cc: Ludwig Zenz <lzenz@dh-electronics.com>
+Cc: NXP Linux Team <linux-imx@nxp.com>
+Cc: Shawn Guo <shawnguo@kernel.org>
+Cc: stable@vger.kernel.org
+Reviewed-by: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/boot/dts/imx6q-dhcom-som.dtsi |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
++++ b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi
+@@ -406,6 +406,18 @@
+       vin-supply = <&sw1_reg>;
+ };
++&reg_pu {
++      vin-supply = <&sw1_reg>;
++};
++
++&reg_vdd1p1 {
++      vin-supply = <&sw2_reg>;
++};
++
++&reg_vdd2p5 {
++      vin-supply = <&sw2_reg>;
++};
++
+ &uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
diff --git a/queue-5.10/ext4-fix-accessing-uninit-percpu-counter-variable-with-fast_commit.patch b/queue-5.10/ext4-fix-accessing-uninit-percpu-counter-variable-with-fast_commit.patch
new file mode 100644 (file)
index 0000000..2ff28a4
--- /dev/null
@@ -0,0 +1,75 @@
+From b45f189a19b38e01676628db79cd3eeb1333516e Mon Sep 17 00:00:00 2001
+From: Ritesh Harjani <riteshh@linux.ibm.com>
+Date: Thu, 29 Apr 2021 16:13:44 +0530
+Subject: ext4: fix accessing uninit percpu counter variable with fast_commit
+
+From: Ritesh Harjani <riteshh@linux.ibm.com>
+
+commit b45f189a19b38e01676628db79cd3eeb1333516e upstream.
+
+When running generic/527 with fast_commit configuration, the following
+issue is seen on Power.  With fast_commit, during ext4_fc_replay()
+(which can be called from ext4_fill_super()), if inode eviction
+happens then it can access an uninitialized percpu counter variable.
+
+This patch adds the check before accessing the counters in
+ext4_free_inode() path.
+
+[  321.165371] run fstests generic/527 at 2021-04-29 08:38:43
+[  323.027786] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: block_validity. Quota mode: none.
+[  323.618772] BUG: Unable to handle kernel data access on read at 0x1fbd80000
+[  323.619767] Faulting instruction address: 0xc000000000bae78c
+cpu 0x1: Vector: 300 (Data Access) at [c000000010706ef0]
+    pc: c000000000bae78c: percpu_counter_add_batch+0x3c/0x100
+    lr: c0000000006d0bb0: ext4_free_inode+0x780/0xb90
+    pid   = 5593, comm = mount
+       ext4_free_inode+0x780/0xb90
+       ext4_evict_inode+0xa8c/0xc60
+       evict+0xfc/0x1e0
+       ext4_fc_replay+0xc50/0x20f0
+       do_one_pass+0xfe0/0x1350
+       jbd2_journal_recover+0x184/0x2e0
+       jbd2_journal_load+0x1c0/0x4a0
+       ext4_fill_super+0x2458/0x4200
+       mount_bdev+0x1dc/0x290
+       ext4_mount+0x28/0x40
+       legacy_get_tree+0x4c/0xa0
+       vfs_get_tree+0x4c/0x120
+       path_mount+0xcf8/0xd70
+       do_mount+0x80/0xd0
+       sys_mount+0x3fc/0x490
+       system_call_exception+0x384/0x3d0
+       system_call_common+0xec/0x278
+
+Cc: stable@kernel.org
+Fixes: 8016e29f4362 ("ext4: fast commit recovery path")
+Signed-off-by: Ritesh Harjani <riteshh@linux.ibm.com>
+Reviewed-by: Harshad Shirwadkar <harshadshirwadkar@gmail.com>
+Link: https://lore.kernel.org/r/6cceb9a75c54bef8fa9696c1b08c8df5ff6169e2.1619692410.git.riteshh@linux.ibm.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/ialloc.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -322,14 +322,16 @@ void ext4_free_inode(handle_t *handle, s
+       if (is_directory) {
+               count = ext4_used_dirs_count(sb, gdp) - 1;
+               ext4_used_dirs_set(sb, gdp, count);
+-              percpu_counter_dec(&sbi->s_dirs_counter);
++              if (percpu_counter_initialized(&sbi->s_dirs_counter))
++                      percpu_counter_dec(&sbi->s_dirs_counter);
+       }
+       ext4_inode_bitmap_csum_set(sb, block_group, gdp, bitmap_bh,
+                                  EXT4_INODES_PER_GROUP(sb) / 8);
+       ext4_group_desc_csum_set(sb, block_group, gdp);
+       ext4_unlock_group(sb, block_group);
+-      percpu_counter_inc(&sbi->s_freeinodes_counter);
++      if (percpu_counter_initialized(&sbi->s_freeinodes_counter))
++              percpu_counter_inc(&sbi->s_freeinodes_counter);
+       if (sbi->s_log_groups_per_flex) {
+               struct flex_groups *fg;
diff --git a/queue-5.10/ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_split_extent_at-failed.patch b/queue-5.10/ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_split_extent_at-failed.patch
new file mode 100644 (file)
index 0000000..6911a2f
--- /dev/null
@@ -0,0 +1,114 @@
+From 082cd4ec240b8734a82a89ffb890216ac98fec68 Mon Sep 17 00:00:00 2001
+From: Ye Bin <yebin10@huawei.com>
+Date: Thu, 6 May 2021 22:10:42 +0800
+Subject: ext4: fix bug on in ext4_es_cache_extent as ext4_split_extent_at failed
+
+From: Ye Bin <yebin10@huawei.com>
+
+commit 082cd4ec240b8734a82a89ffb890216ac98fec68 upstream.
+
+We got follow bug_on when run fsstress with injecting IO fault:
+[130747.323114] kernel BUG at fs/ext4/extents_status.c:762!
+[130747.323117] Internal error: Oops - BUG: 0 [#1] SMP
+......
+[130747.334329] Call trace:
+[130747.334553]  ext4_es_cache_extent+0x150/0x168 [ext4]
+[130747.334975]  ext4_cache_extents+0x64/0xe8 [ext4]
+[130747.335368]  ext4_find_extent+0x300/0x330 [ext4]
+[130747.335759]  ext4_ext_map_blocks+0x74/0x1178 [ext4]
+[130747.336179]  ext4_map_blocks+0x2f4/0x5f0 [ext4]
+[130747.336567]  ext4_mpage_readpages+0x4a8/0x7a8 [ext4]
+[130747.336995]  ext4_readpage+0x54/0x100 [ext4]
+[130747.337359]  generic_file_buffered_read+0x410/0xae8
+[130747.337767]  generic_file_read_iter+0x114/0x190
+[130747.338152]  ext4_file_read_iter+0x5c/0x140 [ext4]
+[130747.338556]  __vfs_read+0x11c/0x188
+[130747.338851]  vfs_read+0x94/0x150
+[130747.339110]  ksys_read+0x74/0xf0
+
+This patch's modification is according to Jan Kara's suggestion in:
+https://patchwork.ozlabs.org/project/linux-ext4/patch/20210428085158.3728201-1-yebin10@huawei.com/
+"I see. Now I understand your patch. Honestly, seeing how fragile is trying
+to fix extent tree after split has failed in the middle, I would probably
+go even further and make sure we fix the tree properly in case of ENOSPC
+and EDQUOT (those are easily user triggerable).  Anything else indicates a
+HW problem or fs corruption so I'd rather leave the extent tree as is and
+don't try to fix it (which also means we will not create overlapping
+extents)."
+
+Cc: stable@kernel.org
+Signed-off-by: Ye Bin <yebin10@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20210506141042.3298679-1-yebin10@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/extents.c |   43 +++++++++++++++++++++++--------------------
+ 1 file changed, 23 insertions(+), 20 deletions(-)
+
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -3206,7 +3206,10 @@ static int ext4_split_extent_at(handle_t
+               ext4_ext_mark_unwritten(ex2);
+       err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
+-      if (err == -ENOSPC && (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
++      if (err != -ENOSPC && err != -EDQUOT)
++              goto out;
++
++      if (EXT4_EXT_MAY_ZEROOUT & split_flag) {
+               if (split_flag & (EXT4_EXT_DATA_VALID1|EXT4_EXT_DATA_VALID2)) {
+                       if (split_flag & EXT4_EXT_DATA_VALID1) {
+                               err = ext4_ext_zeroout(inode, ex2);
+@@ -3232,25 +3235,22 @@ static int ext4_split_extent_at(handle_t
+                                             ext4_ext_pblock(&orig_ex));
+               }
+-              if (err)
+-                      goto fix_extent_len;
+-              /* update the extent length and mark as initialized */
+-              ex->ee_len = cpu_to_le16(ee_len);
+-              ext4_ext_try_to_merge(handle, inode, path, ex);
+-              err = ext4_ext_dirty(handle, inode, path + path->p_depth);
+-              if (err)
+-                      goto fix_extent_len;
+-
+-              /* update extent status tree */
+-              err = ext4_zeroout_es(inode, &zero_ex);
+-
+-              goto out;
+-      } else if (err)
+-              goto fix_extent_len;
+-
+-out:
+-      ext4_ext_show_leaf(inode, path);
+-      return err;
++              if (!err) {
++                      /* update the extent length and mark as initialized */
++                      ex->ee_len = cpu_to_le16(ee_len);
++                      ext4_ext_try_to_merge(handle, inode, path, ex);
++                      err = ext4_ext_dirty(handle, inode, path + path->p_depth);
++                      if (!err)
++                              /* update extent status tree */
++                              err = ext4_zeroout_es(inode, &zero_ex);
++                      /* If we failed at this point, we don't know in which
++                       * state the extent tree exactly is so don't try to fix
++                       * length of the original extent as it may do even more
++                       * damage.
++                       */
++                      goto out;
++              }
++      }
+ fix_extent_len:
+       ex->ee_len = orig_ex.ee_len;
+@@ -3260,6 +3260,9 @@ fix_extent_len:
+        */
+       ext4_ext_dirty(handle, inode, path + path->p_depth);
+       return err;
++out:
++      ext4_ext_show_leaf(inode, path);
++      return err;
+ }
+ /*
diff --git a/queue-5.10/ext4-fix-fast-commit-alignment-issues.patch b/queue-5.10/ext4-fix-fast-commit-alignment-issues.patch
new file mode 100644 (file)
index 0000000..2dd8615
--- /dev/null
@@ -0,0 +1,440 @@
+From a7ba36bc94f20b6c77f16364b9a23f582ea8faac Mon Sep 17 00:00:00 2001
+From: Harshad Shirwadkar <harshadshirwadkar@gmail.com>
+Date: Wed, 19 May 2021 14:59:20 -0700
+Subject: ext4: fix fast commit alignment issues
+
+From: Harshad Shirwadkar <harshadshirwadkar@gmail.com>
+
+commit a7ba36bc94f20b6c77f16364b9a23f582ea8faac upstream.
+
+Fast commit recovery data on disk may not be aligned. So, when the
+recovery code reads it, this patch makes sure that fast commit info
+found on-disk is first memcpy-ed into an aligned variable before
+accessing it. As a consequence of it, we also remove some macros that
+could resulted in unaligned accesses.
+
+Cc: stable@kernel.org
+Fixes: 8016e29f4362 ("ext4: fast commit recovery path")
+Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@gmail.com>
+Link: https://lore.kernel.org/r/20210519215920.2037527-1-harshads@google.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/fast_commit.c |  182 ++++++++++++++++++++++++--------------------------
+ fs/ext4/fast_commit.h |    7 -
+ 2 files changed, 90 insertions(+), 99 deletions(-)
+
+--- a/fs/ext4/fast_commit.c
++++ b/fs/ext4/fast_commit.c
+@@ -1227,18 +1227,6 @@ static void ext4_fc_cleanup(journal_t *j
+ /* Ext4 Replay Path Routines */
+-/* Get length of a particular tlv */
+-static inline int ext4_fc_tag_len(struct ext4_fc_tl *tl)
+-{
+-      return le16_to_cpu(tl->fc_len);
+-}
+-
+-/* Get a pointer to "value" of a tlv */
+-static inline u8 *ext4_fc_tag_val(struct ext4_fc_tl *tl)
+-{
+-      return (u8 *)tl + sizeof(*tl);
+-}
+-
+ /* Helper struct for dentry replay routines */
+ struct dentry_info_args {
+       int parent_ino, dname_len, ino, inode_len;
+@@ -1246,28 +1234,29 @@ struct dentry_info_args {
+ };
+ static inline void tl_to_darg(struct dentry_info_args *darg,
+-                              struct  ext4_fc_tl *tl)
++                            struct  ext4_fc_tl *tl, u8 *val)
+ {
+-      struct ext4_fc_dentry_info *fcd;
++      struct ext4_fc_dentry_info fcd;
+-      fcd = (struct ext4_fc_dentry_info *)ext4_fc_tag_val(tl);
++      memcpy(&fcd, val, sizeof(fcd));
+-      darg->parent_ino = le32_to_cpu(fcd->fc_parent_ino);
+-      darg->ino = le32_to_cpu(fcd->fc_ino);
+-      darg->dname = fcd->fc_dname;
+-      darg->dname_len = ext4_fc_tag_len(tl) -
+-                      sizeof(struct ext4_fc_dentry_info);
++      darg->parent_ino = le32_to_cpu(fcd.fc_parent_ino);
++      darg->ino = le32_to_cpu(fcd.fc_ino);
++      darg->dname = val + offsetof(struct ext4_fc_dentry_info, fc_dname);
++      darg->dname_len = le16_to_cpu(tl->fc_len) -
++              sizeof(struct ext4_fc_dentry_info);
+ }
+ /* Unlink replay function */
+-static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl)
++static int ext4_fc_replay_unlink(struct super_block *sb, struct ext4_fc_tl *tl,
++                               u8 *val)
+ {
+       struct inode *inode, *old_parent;
+       struct qstr entry;
+       struct dentry_info_args darg;
+       int ret = 0;
+-      tl_to_darg(&darg, tl);
++      tl_to_darg(&darg, tl, val);
+       trace_ext4_fc_replay(sb, EXT4_FC_TAG_UNLINK, darg.ino,
+                       darg.parent_ino, darg.dname_len);
+@@ -1357,13 +1346,14 @@ out:
+ }
+ /* Link replay function */
+-static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl)
++static int ext4_fc_replay_link(struct super_block *sb, struct ext4_fc_tl *tl,
++                             u8 *val)
+ {
+       struct inode *inode;
+       struct dentry_info_args darg;
+       int ret = 0;
+-      tl_to_darg(&darg, tl);
++      tl_to_darg(&darg, tl, val);
+       trace_ext4_fc_replay(sb, EXT4_FC_TAG_LINK, darg.ino,
+                       darg.parent_ino, darg.dname_len);
+@@ -1408,9 +1398,10 @@ static int ext4_fc_record_modified_inode
+ /*
+  * Inode replay function
+  */
+-static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl)
++static int ext4_fc_replay_inode(struct super_block *sb, struct ext4_fc_tl *tl,
++                              u8 *val)
+ {
+-      struct ext4_fc_inode *fc_inode;
++      struct ext4_fc_inode fc_inode;
+       struct ext4_inode *raw_inode;
+       struct ext4_inode *raw_fc_inode;
+       struct inode *inode = NULL;
+@@ -1418,9 +1409,9 @@ static int ext4_fc_replay_inode(struct s
+       int inode_len, ino, ret, tag = le16_to_cpu(tl->fc_tag);
+       struct ext4_extent_header *eh;
+-      fc_inode = (struct ext4_fc_inode *)ext4_fc_tag_val(tl);
++      memcpy(&fc_inode, val, sizeof(fc_inode));
+-      ino = le32_to_cpu(fc_inode->fc_ino);
++      ino = le32_to_cpu(fc_inode.fc_ino);
+       trace_ext4_fc_replay(sb, tag, ino, 0, 0);
+       inode = ext4_iget(sb, ino, EXT4_IGET_NORMAL);
+@@ -1432,12 +1423,13 @@ static int ext4_fc_replay_inode(struct s
+       ext4_fc_record_modified_inode(sb, ino);
+-      raw_fc_inode = (struct ext4_inode *)fc_inode->fc_raw_inode;
++      raw_fc_inode = (struct ext4_inode *)
++              (val + offsetof(struct ext4_fc_inode, fc_raw_inode));
+       ret = ext4_get_fc_inode_loc(sb, ino, &iloc);
+       if (ret)
+               goto out;
+-      inode_len = ext4_fc_tag_len(tl) - sizeof(struct ext4_fc_inode);
++      inode_len = le16_to_cpu(tl->fc_len) - sizeof(struct ext4_fc_inode);
+       raw_inode = ext4_raw_inode(&iloc);
+       memcpy(raw_inode, raw_fc_inode, offsetof(struct ext4_inode, i_block));
+@@ -1505,14 +1497,15 @@ out:
+  * inode for which we are trying to create a dentry here, should already have
+  * been replayed before we start here.
+  */
+-static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl)
++static int ext4_fc_replay_create(struct super_block *sb, struct ext4_fc_tl *tl,
++                               u8 *val)
+ {
+       int ret = 0;
+       struct inode *inode = NULL;
+       struct inode *dir = NULL;
+       struct dentry_info_args darg;
+-      tl_to_darg(&darg, tl);
++      tl_to_darg(&darg, tl, val);
+       trace_ext4_fc_replay(sb, EXT4_FC_TAG_CREAT, darg.ino,
+                       darg.parent_ino, darg.dname_len);
+@@ -1591,9 +1584,9 @@ static int ext4_fc_record_regions(struct
+ /* Replay add range tag */
+ static int ext4_fc_replay_add_range(struct super_block *sb,
+-                              struct ext4_fc_tl *tl)
++                                  struct ext4_fc_tl *tl, u8 *val)
+ {
+-      struct ext4_fc_add_range *fc_add_ex;
++      struct ext4_fc_add_range fc_add_ex;
+       struct ext4_extent newex, *ex;
+       struct inode *inode;
+       ext4_lblk_t start, cur;
+@@ -1603,15 +1596,14 @@ static int ext4_fc_replay_add_range(stru
+       struct ext4_ext_path *path = NULL;
+       int ret;
+-      fc_add_ex = (struct ext4_fc_add_range *)ext4_fc_tag_val(tl);
+-      ex = (struct ext4_extent *)&fc_add_ex->fc_ex;
++      memcpy(&fc_add_ex, val, sizeof(fc_add_ex));
++      ex = (struct ext4_extent *)&fc_add_ex.fc_ex;
+       trace_ext4_fc_replay(sb, EXT4_FC_TAG_ADD_RANGE,
+-              le32_to_cpu(fc_add_ex->fc_ino), le32_to_cpu(ex->ee_block),
++              le32_to_cpu(fc_add_ex.fc_ino), le32_to_cpu(ex->ee_block),
+               ext4_ext_get_actual_len(ex));
+-      inode = ext4_iget(sb, le32_to_cpu(fc_add_ex->fc_ino),
+-                              EXT4_IGET_NORMAL);
++      inode = ext4_iget(sb, le32_to_cpu(fc_add_ex.fc_ino), EXT4_IGET_NORMAL);
+       if (IS_ERR(inode)) {
+               jbd_debug(1, "Inode not found.");
+               return 0;
+@@ -1720,32 +1712,33 @@ next:
+ /* Replay DEL_RANGE tag */
+ static int
+-ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl)
++ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl,
++                       u8 *val)
+ {
+       struct inode *inode;
+-      struct ext4_fc_del_range *lrange;
++      struct ext4_fc_del_range lrange;
+       struct ext4_map_blocks map;
+       ext4_lblk_t cur, remaining;
+       int ret;
+-      lrange = (struct ext4_fc_del_range *)ext4_fc_tag_val(tl);
+-      cur = le32_to_cpu(lrange->fc_lblk);
+-      remaining = le32_to_cpu(lrange->fc_len);
++      memcpy(&lrange, val, sizeof(lrange));
++      cur = le32_to_cpu(lrange.fc_lblk);
++      remaining = le32_to_cpu(lrange.fc_len);
+       trace_ext4_fc_replay(sb, EXT4_FC_TAG_DEL_RANGE,
+-              le32_to_cpu(lrange->fc_ino), cur, remaining);
++              le32_to_cpu(lrange.fc_ino), cur, remaining);
+-      inode = ext4_iget(sb, le32_to_cpu(lrange->fc_ino), EXT4_IGET_NORMAL);
++      inode = ext4_iget(sb, le32_to_cpu(lrange.fc_ino), EXT4_IGET_NORMAL);
+       if (IS_ERR(inode)) {
+-              jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange->fc_ino));
++              jbd_debug(1, "Inode %d not found", le32_to_cpu(lrange.fc_ino));
+               return 0;
+       }
+       ret = ext4_fc_record_modified_inode(sb, inode->i_ino);
+       jbd_debug(1, "DEL_RANGE, inode %ld, lblk %d, len %d\n",
+-                      inode->i_ino, le32_to_cpu(lrange->fc_lblk),
+-                      le32_to_cpu(lrange->fc_len));
++                      inode->i_ino, le32_to_cpu(lrange.fc_lblk),
++                      le32_to_cpu(lrange.fc_len));
+       while (remaining > 0) {
+               map.m_lblk = cur;
+               map.m_len = remaining;
+@@ -1766,8 +1759,8 @@ ext4_fc_replay_del_range(struct super_bl
+       }
+       ret = ext4_punch_hole(inode,
+-              le32_to_cpu(lrange->fc_lblk) << sb->s_blocksize_bits,
+-              le32_to_cpu(lrange->fc_len) <<  sb->s_blocksize_bits);
++              le32_to_cpu(lrange.fc_lblk) << sb->s_blocksize_bits,
++              le32_to_cpu(lrange.fc_len) <<  sb->s_blocksize_bits);
+       if (ret)
+               jbd_debug(1, "ext4_punch_hole returned %d", ret);
+       ext4_ext_replay_shrink_inode(inode,
+@@ -1909,11 +1902,11 @@ static int ext4_fc_replay_scan(journal_t
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+       struct ext4_fc_replay_state *state;
+       int ret = JBD2_FC_REPLAY_CONTINUE;
+-      struct ext4_fc_add_range *ext;
+-      struct ext4_fc_tl *tl;
+-      struct ext4_fc_tail *tail;
+-      __u8 *start, *end;
+-      struct ext4_fc_head *head;
++      struct ext4_fc_add_range ext;
++      struct ext4_fc_tl tl;
++      struct ext4_fc_tail tail;
++      __u8 *start, *end, *cur, *val;
++      struct ext4_fc_head head;
+       struct ext4_extent *ex;
+       state = &sbi->s_fc_replay_state;
+@@ -1940,15 +1933,17 @@ static int ext4_fc_replay_scan(journal_t
+       }
+       state->fc_replay_expected_off++;
+-      fc_for_each_tl(start, end, tl) {
++      for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
++              memcpy(&tl, cur, sizeof(tl));
++              val = cur + sizeof(tl);
+               jbd_debug(3, "Scan phase, tag:%s, blk %lld\n",
+-                        tag2str(le16_to_cpu(tl->fc_tag)), bh->b_blocknr);
+-              switch (le16_to_cpu(tl->fc_tag)) {
++                        tag2str(le16_to_cpu(tl.fc_tag)), bh->b_blocknr);
++              switch (le16_to_cpu(tl.fc_tag)) {
+               case EXT4_FC_TAG_ADD_RANGE:
+-                      ext = (struct ext4_fc_add_range *)ext4_fc_tag_val(tl);
+-                      ex = (struct ext4_extent *)&ext->fc_ex;
++                      memcpy(&ext, val, sizeof(ext));
++                      ex = (struct ext4_extent *)&ext.fc_ex;
+                       ret = ext4_fc_record_regions(sb,
+-                              le32_to_cpu(ext->fc_ino),
++                              le32_to_cpu(ext.fc_ino),
+                               le32_to_cpu(ex->ee_block), ext4_ext_pblock(ex),
+                               ext4_ext_get_actual_len(ex));
+                       if (ret < 0)
+@@ -1962,18 +1957,18 @@ static int ext4_fc_replay_scan(journal_t
+               case EXT4_FC_TAG_INODE:
+               case EXT4_FC_TAG_PAD:
+                       state->fc_cur_tag++;
+-                      state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl,
+-                                      sizeof(*tl) + ext4_fc_tag_len(tl));
++                      state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
++                                      sizeof(tl) + le16_to_cpu(tl.fc_len));
+                       break;
+               case EXT4_FC_TAG_TAIL:
+                       state->fc_cur_tag++;
+-                      tail = (struct ext4_fc_tail *)ext4_fc_tag_val(tl);
+-                      state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl,
+-                                              sizeof(*tl) +
++                      memcpy(&tail, val, sizeof(tail));
++                      state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
++                                              sizeof(tl) +
+                                               offsetof(struct ext4_fc_tail,
+                                               fc_crc));
+-                      if (le32_to_cpu(tail->fc_tid) == expected_tid &&
+-                              le32_to_cpu(tail->fc_crc) == state->fc_crc) {
++                      if (le32_to_cpu(tail.fc_tid) == expected_tid &&
++                              le32_to_cpu(tail.fc_crc) == state->fc_crc) {
+                               state->fc_replay_num_tags = state->fc_cur_tag;
+                               state->fc_regions_valid =
+                                       state->fc_regions_used;
+@@ -1984,19 +1979,19 @@ static int ext4_fc_replay_scan(journal_t
+                       state->fc_crc = 0;
+                       break;
+               case EXT4_FC_TAG_HEAD:
+-                      head = (struct ext4_fc_head *)ext4_fc_tag_val(tl);
+-                      if (le32_to_cpu(head->fc_features) &
++                      memcpy(&head, val, sizeof(head));
++                      if (le32_to_cpu(head.fc_features) &
+                               ~EXT4_FC_SUPPORTED_FEATURES) {
+                               ret = -EOPNOTSUPP;
+                               break;
+                       }
+-                      if (le32_to_cpu(head->fc_tid) != expected_tid) {
++                      if (le32_to_cpu(head.fc_tid) != expected_tid) {
+                               ret = JBD2_FC_REPLAY_STOP;
+                               break;
+                       }
+                       state->fc_cur_tag++;
+-                      state->fc_crc = ext4_chksum(sbi, state->fc_crc, tl,
+-                                      sizeof(*tl) + ext4_fc_tag_len(tl));
++                      state->fc_crc = ext4_chksum(sbi, state->fc_crc, cur,
++                                          sizeof(tl) + le16_to_cpu(tl.fc_len));
+                       break;
+               default:
+                       ret = state->fc_replay_num_tags ?
+@@ -2020,11 +2015,11 @@ static int ext4_fc_replay(journal_t *jou
+ {
+       struct super_block *sb = journal->j_private;
+       struct ext4_sb_info *sbi = EXT4_SB(sb);
+-      struct ext4_fc_tl *tl;
+-      __u8 *start, *end;
++      struct ext4_fc_tl tl;
++      __u8 *start, *end, *cur, *val;
+       int ret = JBD2_FC_REPLAY_CONTINUE;
+       struct ext4_fc_replay_state *state = &sbi->s_fc_replay_state;
+-      struct ext4_fc_tail *tail;
++      struct ext4_fc_tail tail;
+       if (pass == PASS_SCAN) {
+               state->fc_current_pass = PASS_SCAN;
+@@ -2051,49 +2046,52 @@ static int ext4_fc_replay(journal_t *jou
+       start = (u8 *)bh->b_data;
+       end = (__u8 *)bh->b_data + journal->j_blocksize - 1;
+-      fc_for_each_tl(start, end, tl) {
++      for (cur = start; cur < end; cur = cur + sizeof(tl) + le16_to_cpu(tl.fc_len)) {
++              memcpy(&tl, cur, sizeof(tl));
++              val = cur + sizeof(tl);
++
+               if (state->fc_replay_num_tags == 0) {
+                       ret = JBD2_FC_REPLAY_STOP;
+                       ext4_fc_set_bitmaps_and_counters(sb);
+                       break;
+               }
+               jbd_debug(3, "Replay phase, tag:%s\n",
+-                              tag2str(le16_to_cpu(tl->fc_tag)));
++                              tag2str(le16_to_cpu(tl.fc_tag)));
+               state->fc_replay_num_tags--;
+-              switch (le16_to_cpu(tl->fc_tag)) {
++              switch (le16_to_cpu(tl.fc_tag)) {
+               case EXT4_FC_TAG_LINK:
+-                      ret = ext4_fc_replay_link(sb, tl);
++                      ret = ext4_fc_replay_link(sb, &tl, val);
+                       break;
+               case EXT4_FC_TAG_UNLINK:
+-                      ret = ext4_fc_replay_unlink(sb, tl);
++                      ret = ext4_fc_replay_unlink(sb, &tl, val);
+                       break;
+               case EXT4_FC_TAG_ADD_RANGE:
+-                      ret = ext4_fc_replay_add_range(sb, tl);
++                      ret = ext4_fc_replay_add_range(sb, &tl, val);
+                       break;
+               case EXT4_FC_TAG_CREAT:
+-                      ret = ext4_fc_replay_create(sb, tl);
++                      ret = ext4_fc_replay_create(sb, &tl, val);
+                       break;
+               case EXT4_FC_TAG_DEL_RANGE:
+-                      ret = ext4_fc_replay_del_range(sb, tl);
++                      ret = ext4_fc_replay_del_range(sb, &tl, val);
+                       break;
+               case EXT4_FC_TAG_INODE:
+-                      ret = ext4_fc_replay_inode(sb, tl);
++                      ret = ext4_fc_replay_inode(sb, &tl, val);
+                       break;
+               case EXT4_FC_TAG_PAD:
+                       trace_ext4_fc_replay(sb, EXT4_FC_TAG_PAD, 0,
+-                              ext4_fc_tag_len(tl), 0);
++                                           le16_to_cpu(tl.fc_len), 0);
+                       break;
+               case EXT4_FC_TAG_TAIL:
+                       trace_ext4_fc_replay(sb, EXT4_FC_TAG_TAIL, 0,
+-                              ext4_fc_tag_len(tl), 0);
+-                      tail = (struct ext4_fc_tail *)ext4_fc_tag_val(tl);
+-                      WARN_ON(le32_to_cpu(tail->fc_tid) != expected_tid);
++                                           le16_to_cpu(tl.fc_len), 0);
++                      memcpy(&tail, val, sizeof(tail));
++                      WARN_ON(le32_to_cpu(tail.fc_tid) != expected_tid);
+                       break;
+               case EXT4_FC_TAG_HEAD:
+                       break;
+               default:
+-                      trace_ext4_fc_replay(sb, le16_to_cpu(tl->fc_tag), 0,
+-                              ext4_fc_tag_len(tl), 0);
++                      trace_ext4_fc_replay(sb, le16_to_cpu(tl.fc_tag), 0,
++                                           le16_to_cpu(tl.fc_len), 0);
+                       ret = -ECANCELED;
+                       break;
+               }
+--- a/fs/ext4/fast_commit.h
++++ b/fs/ext4/fast_commit.h
+@@ -146,12 +146,5 @@ struct ext4_fc_replay_state {
+ #define region_last(__region) (((__region)->lblk) + ((__region)->len) - 1)
+-#define fc_for_each_tl(__start, __end, __tl)                          \
+-      for (tl = (struct ext4_fc_tl *)start;                           \
+-              (u8 *)tl < (u8 *)end;                                   \
+-              tl = (struct ext4_fc_tl *)((u8 *)tl +                   \
+-                                      sizeof(struct ext4_fc_tl) +     \
+-                                      + le16_to_cpu(tl->fc_len)))
+-
+ #endif /* __FAST_COMMIT_H__ */
diff --git a/queue-5.10/ext4-fix-memory-leak-in-ext4_fill_super.patch b/queue-5.10/ext4-fix-memory-leak-in-ext4_fill_super.patch
new file mode 100644 (file)
index 0000000..a377208
--- /dev/null
@@ -0,0 +1,74 @@
+From afd09b617db3786b6ef3dc43e28fe728cfea84df Mon Sep 17 00:00:00 2001
+From: Alexey Makhalov <amakhalov@vmware.com>
+Date: Fri, 21 May 2021 07:55:33 +0000
+Subject: ext4: fix memory leak in ext4_fill_super
+
+From: Alexey Makhalov <amakhalov@vmware.com>
+
+commit afd09b617db3786b6ef3dc43e28fe728cfea84df upstream.
+
+Buffer head references must be released before calling kill_bdev();
+otherwise the buffer head (and its page referenced by b_data) will not
+be freed by kill_bdev, and subsequently that bh will be leaked.
+
+If blocksizes differ, sb_set_blocksize() will kill current buffers and
+page cache by using kill_bdev(). And then super block will be reread
+again but using correct blocksize this time. sb_set_blocksize() didn't
+fully free superblock page and buffer head, and being busy, they were
+not freed and instead leaked.
+
+This can easily be reproduced by calling an infinite loop of:
+
+  systemctl start <ext4_on_lvm>.mount, and
+  systemctl stop <ext4_on_lvm>.mount
+
+... since systemd creates a cgroup for each slice which it mounts, and
+the bh leak get amplified by a dying memory cgroup that also never
+gets freed, and memory consumption is much more easily noticed.
+
+Fixes: ce40733ce93d ("ext4: Check for return value from sb_set_blocksize")
+Fixes: ac27a0ec112a ("ext4: initial copy of files from ext3")
+Link: https://lore.kernel.org/r/20210521075533.95732-1-amakhalov@vmware.com
+Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/super.c |   11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4451,14 +4451,20 @@ static int ext4_fill_super(struct super_
+       }
+       if (sb->s_blocksize != blocksize) {
++              /*
++               * bh must be released before kill_bdev(), otherwise
++               * it won't be freed and its page also. kill_bdev()
++               * is called by sb_set_blocksize().
++               */
++              brelse(bh);
+               /* Validate the filesystem blocksize */
+               if (!sb_set_blocksize(sb, blocksize)) {
+                       ext4_msg(sb, KERN_ERR, "bad block size %d",
+                                       blocksize);
++                      bh = NULL;
+                       goto failed_mount;
+               }
+-              brelse(bh);
+               logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
+               offset = do_div(logical_sb_block, blocksize);
+               bh = ext4_sb_bread_unmovable(sb, logical_sb_block);
+@@ -5181,8 +5187,9 @@ failed_mount:
+               kfree(get_qf_name(sb, sbi, i));
+ #endif
+       fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
+-      ext4_blkdev_remove(sbi);
++      /* ext4_blkdev_remove() calls kill_bdev(), release bh before it. */
+       brelse(bh);
++      ext4_blkdev_remove(sbi);
+ out_fail:
+       sb->s_fs_info = NULL;
+       kfree(sbi->s_blockgroup_lock);
diff --git a/queue-5.10/ext4-fix-memory-leak-in-ext4_mb_init_backend-on-error-path.patch b/queue-5.10/ext4-fix-memory-leak-in-ext4_mb_init_backend-on-error-path.patch
new file mode 100644 (file)
index 0000000..7a2d658
--- /dev/null
@@ -0,0 +1,33 @@
+From a8867f4e3809050571c98de7a2d465aff5e4daf5 Mon Sep 17 00:00:00 2001
+From: Phillip Potter <phil@philpotter.co.uk>
+Date: Mon, 12 Apr 2021 08:38:37 +0100
+Subject: ext4: fix memory leak in ext4_mb_init_backend on error path.
+
+From: Phillip Potter <phil@philpotter.co.uk>
+
+commit a8867f4e3809050571c98de7a2d465aff5e4daf5 upstream.
+
+Fix a memory leak discovered by syzbot when a file system is corrupted
+with an illegally large s_log_groups_per_flex.
+
+Reported-by: syzbot+aa12d6106ea4ca1b6aae@syzkaller.appspotmail.com
+Signed-off-by: Phillip Potter <phil@philpotter.co.uk>
+Cc: stable@kernel.org
+Link: https://lore.kernel.org/r/20210412073837.1686-1-phil@philpotter.co.uk
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/mballoc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2738,7 +2738,7 @@ static int ext4_mb_init_backend(struct s
+                */
+               if (sbi->s_es->s_log_groups_per_flex >= 32) {
+                       ext4_msg(sb, KERN_ERR, "too many log groups per flexible block group");
+-                      goto err_freesgi;
++                      goto err_freebuddy;
+               }
+               sbi->s_mb_prefetch = min_t(uint, 1 << sbi->s_es->s_log_groups_per_flex,
+                       BLK_MAX_SEGMENT_SIZE >> (sb->s_blocksize_bits - 9));
diff --git a/queue-5.10/gfs2-fix-scheduling-while-atomic-bug-in-glocks.patch b/queue-5.10/gfs2-fix-scheduling-while-atomic-bug-in-glocks.patch
new file mode 100644 (file)
index 0000000..4492dd3
--- /dev/null
@@ -0,0 +1,40 @@
+From 20265d9a67e40eafd39a8884658ca2e36f05985d Mon Sep 17 00:00:00 2001
+From: Bob Peterson <rpeterso@redhat.com>
+Date: Tue, 18 May 2021 09:12:10 -0400
+Subject: gfs2: fix scheduling while atomic bug in glocks
+
+From: Bob Peterson <rpeterso@redhat.com>
+
+commit 20265d9a67e40eafd39a8884658ca2e36f05985d upstream.
+
+Before this patch, in the unlikely event that gfs2_glock_dq encountered
+a withdraw, it would do a wait_on_bit to wait for its journal to be
+recovered, but it never released the glock's spin_lock, which caused a
+scheduling-while-atomic error.
+
+This patch unlocks the lockref spin_lock before waiting for recovery.
+
+Fixes: 601ef0d52e96 ("gfs2: Force withdraw to replay journals and wait for it to finish")
+Cc: stable@vger.kernel.org # v5.7+
+Reported-by: Alexander Aring <aahringo@redhat.com>
+Signed-off-by: Bob Peterson <rpeterso@redhat.com>
+Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/gfs2/glock.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/gfs2/glock.c
++++ b/fs/gfs2/glock.c
+@@ -1457,9 +1457,11 @@ void gfs2_glock_dq(struct gfs2_holder *g
+           glock_blocked_by_withdraw(gl) &&
+           gh->gh_gl != sdp->sd_jinode_gl) {
+               sdp->sd_glock_dqs_held++;
++              spin_unlock(&gl->gl_lockref.lock);
+               might_sleep();
+               wait_on_bit(&sdp->sd_flags, SDF_WITHDRAW_RECOVERY,
+                           TASK_UNINTERRUPTIBLE);
++              spin_lock(&gl->gl_lockref.lock);
+       }
+       if (gh->gh_flags & GL_NOCACHE)
+               handle_callback(gl, LM_ST_UNLOCKED, 0, false);
diff --git a/queue-5.10/hid-i2c-hid-skip-elan-power-on-command-after-reset.patch b/queue-5.10/hid-i2c-hid-skip-elan-power-on-command-after-reset.patch
new file mode 100644 (file)
index 0000000..8dd34df
--- /dev/null
@@ -0,0 +1,63 @@
+From ca66a6770bd9d6d99e469debd1c7363ac455daf9 Mon Sep 17 00:00:00 2001
+From: Johnny Chuang <johnny.chuang.emc@gmail.com>
+Date: Tue, 13 Apr 2021 09:20:50 +0800
+Subject: HID: i2c-hid: Skip ELAN power-on command after reset
+
+From: Johnny Chuang <johnny.chuang.emc@gmail.com>
+
+commit ca66a6770bd9d6d99e469debd1c7363ac455daf9 upstream.
+
+For ELAN touchscreen, we found our boot code of IC was not flexible enough
+to receive and handle this command.
+Once the FW main code of our controller is crashed for some reason,
+the controller could not be enumerated successfully to be recognized
+by the system host. therefore, it lost touch functionality.
+
+Add quirk for skip send power-on command after reset.
+It will impact to ELAN touchscreen and touchpad on HID over I2C projects.
+
+Fixes: 43b7029f475e ("HID: i2c-hid: Send power-on command after reset").
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Johnny Chuang <johnny.chuang.emc@gmail.com>
+Reviewed-by: Harry Cutts <hcutts@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Tested-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/i2c-hid/i2c-hid-core.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/hid/i2c-hid/i2c-hid-core.c
++++ b/drivers/hid/i2c-hid/i2c-hid-core.c
+@@ -50,6 +50,7 @@
+ #define I2C_HID_QUIRK_BOGUS_IRQ                       BIT(4)
+ #define I2C_HID_QUIRK_RESET_ON_RESUME         BIT(5)
+ #define I2C_HID_QUIRK_BAD_INPUT_SIZE          BIT(6)
++#define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET   BIT(7)
+ /* flags */
+@@ -183,6 +184,11 @@ static const struct i2c_hid_quirks {
+                I2C_HID_QUIRK_RESET_ON_RESUME },
+       { USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720,
+               I2C_HID_QUIRK_BAD_INPUT_SIZE },
++      /*
++       * Sending the wakeup after reset actually break ELAN touchscreen controller
++       */
++      { USB_VENDOR_ID_ELAN, HID_ANY_ID,
++               I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET },
+       { 0, 0 }
+ };
+@@ -466,7 +472,8 @@ static int i2c_hid_hwreset(struct i2c_cl
+       }
+       /* At least some SIS devices need this after reset */
+-      ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
++      if (!(ihid->quirks & I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET))
++              ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
+ out_unlock:
+       mutex_unlock(&ihid->reset_lock);
diff --git a/queue-5.10/hid-magicmouse-fix-null-deref-on-disconnect.patch b/queue-5.10/hid-magicmouse-fix-null-deref-on-disconnect.patch
new file mode 100644 (file)
index 0000000..eb09119
--- /dev/null
@@ -0,0 +1,39 @@
+From 4b4f6cecca446abcb686c6e6c451d4f1ec1a7497 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Mon, 17 May 2021 12:04:30 +0200
+Subject: HID: magicmouse: fix NULL-deref on disconnect
+
+From: Johan Hovold <johan@kernel.org>
+
+commit 4b4f6cecca446abcb686c6e6c451d4f1ec1a7497 upstream.
+
+Commit 9d7b18668956 ("HID: magicmouse: add support for Apple Magic
+Trackpad 2") added a sanity check for an Apple trackpad but returned
+success instead of -ENODEV when the check failed. This means that the
+remove callback will dereference the never-initialised driver data
+pointer when the driver is later unbound (e.g. on USB disconnect).
+
+Reported-by: syzbot+ee6f6e2e68886ca256a8@syzkaller.appspotmail.com
+Fixes: 9d7b18668956 ("HID: magicmouse: add support for Apple Magic Trackpad 2")
+Cc: stable@vger.kernel.org      # 4.20
+Cc: Claudio Mettler <claudio@ponyfleisch.ch>
+Cc: Marek Wyborski <marek.wyborski@emwesoft.com>
+Cc: Sean O'Brien <seobrien@chromium.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-magicmouse.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hid/hid-magicmouse.c
++++ b/drivers/hid/hid-magicmouse.c
+@@ -597,7 +597,7 @@ static int magicmouse_probe(struct hid_d
+       if (id->vendor == USB_VENDOR_ID_APPLE &&
+           id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+           hdev->type != HID_TYPE_USBMOUSE)
+-              return 0;
++              return -ENODEV;
+       msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL);
+       if (msc == NULL) {
diff --git a/queue-5.10/hid-multitouch-require-finger-field-to-mark-win8-reports-as-mt.patch b/queue-5.10/hid-multitouch-require-finger-field-to-mark-win8-reports-as-mt.patch
new file mode 100644 (file)
index 0000000..84ac39a
--- /dev/null
@@ -0,0 +1,50 @@
+From a2353e3b26012ff43bcdf81d37a3eaddd7ecdbf3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ahelenia=20Ziemia=C5=84ska?=
+ <nabijaczleweli@nabijaczleweli.xyz>
+Date: Mon, 8 Mar 2021 18:42:03 +0100
+Subject: HID: multitouch: require Finger field to mark Win8 reports as MT
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
+
+commit a2353e3b26012ff43bcdf81d37a3eaddd7ecdbf3 upstream.
+
+This effectively changes collection_is_mt from
+  contact ID in report->field
+to
+  (device is Win8 => collection is finger) && contact ID in report->field
+
+Some devices erroneously report Pen for fingers, and Win8 stylus-on-touchscreen
+devices report contact ID, but mark the accompanying touchscreen device's
+collection correctly
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
+Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-multitouch.c |   10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -604,9 +604,13 @@ static struct mt_report_data *mt_allocat
+               if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
+                       continue;
+-              for (n = 0; n < field->report_count; n++) {
+-                      if (field->usage[n].hid == HID_DG_CONTACTID)
+-                              rdata->is_mt_collection = true;
++              if (field->logical == HID_DG_FINGER || td->hdev->group != HID_GROUP_MULTITOUCH_WIN_8) {
++                      for (n = 0; n < field->report_count; n++) {
++                              if (field->usage[n].hid == HID_DG_CONTACTID) {
++                                      rdata->is_mt_collection = true;
++                                      break;
++                              }
++                      }
+               }
+       }
diff --git a/queue-5.10/net-caif-add-proper-error-handling.patch b/queue-5.10/net-caif-add-proper-error-handling.patch
new file mode 100644 (file)
index 0000000..b7246a1
--- /dev/null
@@ -0,0 +1,152 @@
+From a2805dca5107d5603f4bbc027e81e20d93476e96 Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Thu, 3 Jun 2021 19:38:51 +0300
+Subject: net: caif: add proper error handling
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit a2805dca5107d5603f4bbc027e81e20d93476e96 upstream.
+
+caif_enroll_dev() can fail in some cases. Ingnoring
+these cases can lead to memory leak due to not assigning
+link_support pointer to anywhere.
+
+Fixes: 7c18d2205ea7 ("caif: Restructure how link caif link layer enroll")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/caif/caif_dev.h |    2 +-
+ include/net/caif/cfcnfg.h   |    2 +-
+ net/caif/caif_dev.c         |    8 +++++---
+ net/caif/cfcnfg.c           |   16 +++++++++++-----
+ 4 files changed, 18 insertions(+), 10 deletions(-)
+
+--- a/include/net/caif/caif_dev.h
++++ b/include/net/caif/caif_dev.h
+@@ -119,7 +119,7 @@ void caif_free_client(struct cflayer *ad
+  * The link_support layer is used to add any Link Layer specific
+  * framing.
+  */
+-void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
++int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
+                       struct cflayer *link_support, int head_room,
+                       struct cflayer **layer, int (**rcv_func)(
+                               struct sk_buff *, struct net_device *,
+--- a/include/net/caif/cfcnfg.h
++++ b/include/net/caif/cfcnfg.h
+@@ -62,7 +62,7 @@ void cfcnfg_remove(struct cfcnfg *cfg);
+  * @fcs:      Specify if checksum is used in CAIF Framing Layer.
+  * @head_room:        Head space needed by link specific protocol.
+  */
+-void
++int
+ cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
+                    struct net_device *dev, struct cflayer *phy_layer,
+                    enum cfcnfg_phy_preference pref,
+--- a/net/caif/caif_dev.c
++++ b/net/caif/caif_dev.c
+@@ -308,7 +308,7 @@ static void dev_flowctrl(struct net_devi
+       caifd_put(caifd);
+ }
+-void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
++int caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev,
+                    struct cflayer *link_support, int head_room,
+                    struct cflayer **layer,
+                    int (**rcv_func)(struct sk_buff *, struct net_device *,
+@@ -319,11 +319,12 @@ void caif_enroll_dev(struct net_device *
+       enum cfcnfg_phy_preference pref;
+       struct cfcnfg *cfg = get_cfcnfg(dev_net(dev));
+       struct caif_device_entry_list *caifdevs;
++      int res;
+       caifdevs = caif_device_list(dev_net(dev));
+       caifd = caif_device_alloc(dev);
+       if (!caifd)
+-              return;
++              return -ENOMEM;
+       *layer = &caifd->layer;
+       spin_lock_init(&caifd->flow_lock);
+@@ -344,7 +345,7 @@ void caif_enroll_dev(struct net_device *
+       strlcpy(caifd->layer.name, dev->name,
+               sizeof(caifd->layer.name));
+       caifd->layer.transmit = transmit;
+-      cfcnfg_add_phy_layer(cfg,
++      res = cfcnfg_add_phy_layer(cfg,
+                               dev,
+                               &caifd->layer,
+                               pref,
+@@ -354,6 +355,7 @@ void caif_enroll_dev(struct net_device *
+       mutex_unlock(&caifdevs->lock);
+       if (rcv_func)
+               *rcv_func = receive;
++      return res;
+ }
+ EXPORT_SYMBOL(caif_enroll_dev);
+--- a/net/caif/cfcnfg.c
++++ b/net/caif/cfcnfg.c
+@@ -450,7 +450,7 @@ unlock:
+       rcu_read_unlock();
+ }
+-void
++int
+ cfcnfg_add_phy_layer(struct cfcnfg *cnfg,
+                    struct net_device *dev, struct cflayer *phy_layer,
+                    enum cfcnfg_phy_preference pref,
+@@ -459,7 +459,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg
+ {
+       struct cflayer *frml;
+       struct cfcnfg_phyinfo *phyinfo = NULL;
+-      int i;
++      int i, res = 0;
+       u8 phyid;
+       mutex_lock(&cnfg->lock);
+@@ -473,12 +473,15 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg
+                       goto got_phyid;
+       }
+       pr_warn("Too many CAIF Link Layers (max 6)\n");
++      res = -EEXIST;
+       goto out;
+ got_phyid:
+       phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC);
+-      if (!phyinfo)
++      if (!phyinfo) {
++              res = -ENOMEM;
+               goto out_err;
++      }
+       phy_layer->id = phyid;
+       phyinfo->pref = pref;
+@@ -492,8 +495,10 @@ got_phyid:
+       frml = cffrml_create(phyid, fcs);
+-      if (!frml)
++      if (!frml) {
++              res = -ENOMEM;
+               goto out_err;
++      }
+       phyinfo->frm_layer = frml;
+       layer_set_up(frml, cnfg->mux);
+@@ -511,11 +516,12 @@ got_phyid:
+       list_add_rcu(&phyinfo->node, &cnfg->phys);
+ out:
+       mutex_unlock(&cnfg->lock);
+-      return;
++      return res;
+ out_err:
+       kfree(phyinfo);
+       mutex_unlock(&cnfg->lock);
++      return res;
+ }
+ EXPORT_SYMBOL(cfcnfg_add_phy_layer);
diff --git a/queue-5.10/net-caif-added-cfserl_release-function.patch b/queue-5.10/net-caif-added-cfserl_release-function.patch
new file mode 100644 (file)
index 0000000..113cf4e
--- /dev/null
@@ -0,0 +1,42 @@
+From bce130e7f392ddde8cfcb09927808ebd5f9c8669 Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Thu, 3 Jun 2021 19:38:12 +0300
+Subject: net: caif: added cfserl_release function
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit bce130e7f392ddde8cfcb09927808ebd5f9c8669 upstream.
+
+Added cfserl_release() function.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/caif/cfserl.h |    1 +
+ net/caif/cfserl.c         |    5 +++++
+ 2 files changed, 6 insertions(+)
+
+--- a/include/net/caif/cfserl.h
++++ b/include/net/caif/cfserl.h
+@@ -9,4 +9,5 @@
+ #include <net/caif/caif_layer.h>
+ struct cflayer *cfserl_create(int instance, bool use_stx);
++void cfserl_release(struct cflayer *layer);
+ #endif
+--- a/net/caif/cfserl.c
++++ b/net/caif/cfserl.c
+@@ -31,6 +31,11 @@ static int cfserl_transmit(struct cflaye
+ static void cfserl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
+                          int phyid);
++void cfserl_release(struct cflayer *layer)
++{
++      kfree(layer);
++}
++
+ struct cflayer *cfserl_create(int instance, bool use_stx)
+ {
+       struct cfserl *this = kzalloc(sizeof(struct cfserl), GFP_ATOMIC);
diff --git a/queue-5.10/net-caif-fix-memory-leak-in-caif_device_notify.patch b/queue-5.10/net-caif-fix-memory-leak-in-caif_device_notify.patch
new file mode 100644 (file)
index 0000000..db0db89
--- /dev/null
@@ -0,0 +1,46 @@
+From b53558a950a89824938e9811eddfc8efcd94e1bb Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Thu, 3 Jun 2021 19:39:11 +0300
+Subject: net: caif: fix memory leak in caif_device_notify
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit b53558a950a89824938e9811eddfc8efcd94e1bb upstream.
+
+In case of caif_enroll_dev() fail, allocated
+link_support won't be assigned to the corresponding
+structure. So simply free allocated pointer in case
+of error
+
+Fixes: 7c18d2205ea7 ("caif: Restructure how link caif link layer enroll")
+Cc: stable@vger.kernel.org
+Reported-and-tested-by: syzbot+7ec324747ce876a29db6@syzkaller.appspotmail.com
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/caif/caif_dev.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/net/caif/caif_dev.c
++++ b/net/caif/caif_dev.c
+@@ -370,6 +370,7 @@ static int caif_device_notify(struct not
+       struct cflayer *layer, *link_support;
+       int head_room = 0;
+       struct caif_device_entry_list *caifdevs;
++      int res;
+       cfg = get_cfcnfg(dev_net(dev));
+       caifdevs = caif_device_list(dev_net(dev));
+@@ -395,8 +396,10 @@ static int caif_device_notify(struct not
+                               break;
+                       }
+               }
+-              caif_enroll_dev(dev, caifdev, link_support, head_room,
++              res = caif_enroll_dev(dev, caifdev, link_support, head_room,
+                               &layer, NULL);
++              if (res)
++                      cfserl_release(link_support);
+               caifdev->flowctrl = dev_flowctrl;
+               break;
diff --git a/queue-5.10/net-caif-fix-memory-leak-in-cfusbl_device_notify.patch b/queue-5.10/net-caif-fix-memory-leak-in-cfusbl_device_notify.patch
new file mode 100644 (file)
index 0000000..f0caac0
--- /dev/null
@@ -0,0 +1,68 @@
+From 7f5d86669fa4d485523ddb1d212e0a2d90bd62bb Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Thu, 3 Jun 2021 19:39:35 +0300
+Subject: net: caif: fix memory leak in cfusbl_device_notify
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit 7f5d86669fa4d485523ddb1d212e0a2d90bd62bb upstream.
+
+In case of caif_enroll_dev() fail, allocated
+link_support won't be assigned to the corresponding
+structure. So simply free allocated pointer in case
+of error.
+
+Fixes: 7ad65bf68d70 ("caif: Add support for CAIF over CDC NCM USB interface")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/caif/caif_usb.c |   14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/net/caif/caif_usb.c
++++ b/net/caif/caif_usb.c
+@@ -115,6 +115,11 @@ static struct cflayer *cfusbl_create(int
+       return (struct cflayer *) this;
+ }
++static void cfusbl_release(struct cflayer *layer)
++{
++      kfree(layer);
++}
++
+ static struct packet_type caif_usb_type __read_mostly = {
+       .type = cpu_to_be16(ETH_P_802_EX1),
+ };
+@@ -127,6 +132,7 @@ static int cfusbl_device_notify(struct n
+       struct cflayer *layer, *link_support;
+       struct usbnet *usbnet;
+       struct usb_device *usbdev;
++      int res;
+       /* Check whether we have a NCM device, and find its VID/PID. */
+       if (!(dev->dev.parent && dev->dev.parent->driver &&
+@@ -169,8 +175,11 @@ static int cfusbl_device_notify(struct n
+       if (dev->num_tx_queues > 1)
+               pr_warn("USB device uses more than one tx queue\n");
+-      caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN,
++      res = caif_enroll_dev(dev, &common, link_support, CFUSB_MAX_HEADLEN,
+                       &layer, &caif_usb_type.func);
++      if (res)
++              goto err;
++
+       if (!pack_added)
+               dev_add_pack(&caif_usb_type);
+       pack_added = true;
+@@ -178,6 +187,9 @@ static int cfusbl_device_notify(struct n
+       strlcpy(layer->name, dev->name, sizeof(layer->name));
+       return 0;
++err:
++      cfusbl_release(link_support);
++      return res;
+ }
+ static struct notifier_block caif_device_notifier = {
diff --git a/queue-5.10/net-kcm-fix-memory-leak-in-kcm_sendmsg.patch b/queue-5.10/net-kcm-fix-memory-leak-in-kcm_sendmsg.patch
new file mode 100644 (file)
index 0000000..6913173
--- /dev/null
@@ -0,0 +1,52 @@
+From c47cc304990a2813995b1a92bbc11d0bb9a19ea9 Mon Sep 17 00:00:00 2001
+From: Pavel Skripkin <paskripkin@gmail.com>
+Date: Wed, 2 Jun 2021 22:26:40 +0300
+Subject: net: kcm: fix memory leak in kcm_sendmsg
+
+From: Pavel Skripkin <paskripkin@gmail.com>
+
+commit c47cc304990a2813995b1a92bbc11d0bb9a19ea9 upstream.
+
+Syzbot reported memory leak in kcm_sendmsg()[1].
+The problem was in non-freed frag_list in case of error.
+
+In the while loop:
+
+       if (head == skb)
+               skb_shinfo(head)->frag_list = tskb;
+       else
+               skb->next = tskb;
+
+frag_list filled with skbs, but nothing was freeing them.
+
+backtrace:
+  [<0000000094c02615>] __alloc_skb+0x5e/0x250 net/core/skbuff.c:198
+  [<00000000e5386cbd>] alloc_skb include/linux/skbuff.h:1083 [inline]
+  [<00000000e5386cbd>] kcm_sendmsg+0x3b6/0xa50 net/kcm/kcmsock.c:967 [1]
+  [<00000000f1613a8a>] sock_sendmsg_nosec net/socket.c:652 [inline]
+  [<00000000f1613a8a>] sock_sendmsg+0x4c/0x60 net/socket.c:672
+
+Reported-and-tested-by: syzbot+b039f5699bd82e1fb011@syzkaller.appspotmail.com
+Fixes: ab7ac4eb9832 ("kcm: Kernel Connection Multiplexor module")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/kcm/kcmsock.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/net/kcm/kcmsock.c
++++ b/net/kcm/kcmsock.c
+@@ -1066,6 +1066,11 @@ out_error:
+               goto partial_message;
+       }
++      if (skb_has_frag_list(head)) {
++              kfree_skb_list(skb_shinfo(head)->frag_list);
++              skb_shinfo(head)->frag_list = NULL;
++      }
++
+       if (head != kcm->seq_skb)
+               kfree_skb(head);
index 62bd9b5abab510a77e8876cfa822f120d33d4247..af4e0cb0224ed49a0b3a46479b88fb5d188cfe02 100644 (file)
@@ -86,3 +86,22 @@ wireguard-allowedips-initialize-list-head-in-selftest.patch
 wireguard-allowedips-remove-nodes-in-o-1.patch
 wireguard-allowedips-allocate-nodes-in-kmem_cache.patch
 wireguard-allowedips-free-empty-intermediate-nodes-when-removing-single-node.patch
+net-kcm-fix-memory-leak-in-kcm_sendmsg.patch
+net-caif-added-cfserl_release-function.patch
+net-caif-add-proper-error-handling.patch
+net-caif-fix-memory-leak-in-caif_device_notify.patch
+net-caif-fix-memory-leak-in-cfusbl_device_notify.patch
+hid-i2c-hid-skip-elan-power-on-command-after-reset.patch
+hid-magicmouse-fix-null-deref-on-disconnect.patch
+hid-multitouch-require-finger-field-to-mark-win8-reports-as-mt.patch
+gfs2-fix-scheduling-while-atomic-bug-in-glocks.patch
+alsa-timer-fix-master-timer-notification.patch
+alsa-hda-fix-for-mute-key-led-for-hp-pavilion-15-ck0xx.patch
+alsa-hda-update-the-power_state-during-the-direct-complete.patch
+arm-dts-imx6dl-yapp4-fix-rgmii-connection-to-qca8334-switch.patch
+arm-dts-imx6q-dhcom-add-pu-vdd1p1-vdd2p5-regulators.patch
+ext4-fix-memory-leak-in-ext4_fill_super.patch
+ext4-fix-bug-on-in-ext4_es_cache_extent-as-ext4_split_extent_at-failed.patch
+ext4-fix-fast-commit-alignment-issues.patch
+ext4-fix-memory-leak-in-ext4_mb_init_backend-on-error-path.patch
+ext4-fix-accessing-uninit-percpu-counter-variable-with-fast_commit.patch