]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.5-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Mar 2020 18:30:40 +0000 (19:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 Mar 2020 18:30:40 +0000 (19:30 +0100)
added patches:
alsa-hda-realtek-add-headset-button-supported-for-thinkpad-x1.patch
alsa-hda-realtek-add-headset-mic-supported.patch
alsa-hda-realtek-enable-the-headset-of-asus-b9450fa-with-alc294.patch
alsa-hda-realtek-fix-a-regression-for-mute-led-on-lenovo-carbon-x1.patch
alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-master.patch
binder-prevent-uaf-for-binderfs-devices-ii.patch
binder-prevent-uaf-for-binderfs-devices.patch
cifs-don-t-leak-eagain-for-stat-during-reconnect.patch
cifs-fix-rename-by-ensuring-source-handle-opened-with-delete-bit.patch
driver-core-call-sync_state-even-if-supplier-has-no-consumers.patch
firmware-imx-scu-ensure-sequential-tx.patch

12 files changed:
queue-5.5/alsa-hda-realtek-add-headset-button-supported-for-thinkpad-x1.patch [new file with mode: 0644]
queue-5.5/alsa-hda-realtek-add-headset-mic-supported.patch [new file with mode: 0644]
queue-5.5/alsa-hda-realtek-enable-the-headset-of-asus-b9450fa-with-alc294.patch [new file with mode: 0644]
queue-5.5/alsa-hda-realtek-fix-a-regression-for-mute-led-on-lenovo-carbon-x1.patch [new file with mode: 0644]
queue-5.5/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-master.patch [new file with mode: 0644]
queue-5.5/binder-prevent-uaf-for-binderfs-devices-ii.patch [new file with mode: 0644]
queue-5.5/binder-prevent-uaf-for-binderfs-devices.patch [new file with mode: 0644]
queue-5.5/cifs-don-t-leak-eagain-for-stat-during-reconnect.patch [new file with mode: 0644]
queue-5.5/cifs-fix-rename-by-ensuring-source-handle-opened-with-delete-bit.patch [new file with mode: 0644]
queue-5.5/driver-core-call-sync_state-even-if-supplier-has-no-consumers.patch [new file with mode: 0644]
queue-5.5/firmware-imx-scu-ensure-sequential-tx.patch [new file with mode: 0644]
queue-5.5/series

diff --git a/queue-5.5/alsa-hda-realtek-add-headset-button-supported-for-thinkpad-x1.patch b/queue-5.5/alsa-hda-realtek-add-headset-button-supported-for-thinkpad-x1.patch
new file mode 100644 (file)
index 0000000..974f25a
--- /dev/null
@@ -0,0 +1,58 @@
+From 76f7dec08fd64e9e3ad0810a1a8a60b0a846d348 Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Mon, 10 Feb 2020 16:30:26 +0800
+Subject: ALSA: hda/realtek - Add Headset Button supported for ThinkPad X1
+
+From: Kailang Yang <kailang@realtek.com>
+
+commit 76f7dec08fd64e9e3ad0810a1a8a60b0a846d348 upstream.
+
+ThinkPad want to support Headset Button control.
+This patch will enable it.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/7f0b7128f40f41f6b5582ff610adc33d@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5920,7 +5920,7 @@ enum {
+       ALC289_FIXUP_DUAL_SPK,
+       ALC294_FIXUP_SPK2_TO_DAC1,
+       ALC294_FIXUP_ASUS_DUAL_SPK,
+-
++      ALC285_FIXUP_THINKPAD_HEADSET_JACK,
+ };
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -7040,7 +7040,12 @@ static const struct hda_fixup alc269_fix
+               .chained = true,
+               .chain_id = ALC294_FIXUP_SPK2_TO_DAC1
+       },
+-
++      [ALC285_FIXUP_THINKPAD_HEADSET_JACK] = {
++              .type = HDA_FIXUP_FUNC,
++              .v.func = alc_fixup_headset_jack,
++              .chained = true,
++              .chain_id = ALC285_FIXUP_SPEAKER2_TO_DAC1
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -7276,8 +7281,8 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK),
+       SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+-      SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
+-      SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_SPEAKER2_TO_DAC1),
++      SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Yoga 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
++      SND_PCI_QUIRK(0x17aa, 0x2293, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK),
+       SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+       SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+       SND_PCI_QUIRK(0x17aa, 0x310c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
diff --git a/queue-5.5/alsa-hda-realtek-add-headset-mic-supported.patch b/queue-5.5/alsa-hda-realtek-add-headset-mic-supported.patch
new file mode 100644 (file)
index 0000000..497fd9d
--- /dev/null
@@ -0,0 +1,34 @@
+From 78def224f59c05d00e815be946ec229719ccf377 Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Thu, 20 Feb 2020 15:21:54 +0800
+Subject: ALSA: hda/realtek - Add Headset Mic supported
+
+From: Kailang Yang <kailang@realtek.com>
+
+commit 78def224f59c05d00e815be946ec229719ccf377 upstream.
+
+Dell desktop platform supported headset Mic.
+Add pin verb to enable headset Mic.
+This platform only support fixed type headset for Iphone type.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/b9da28d772ef43088791b0f3675929e7@realtek.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -7115,6 +7115,8 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
+       SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
+       SND_PCI_QUIRK(0x1028, 0x097d, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
++      SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
++      SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+       SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
diff --git a/queue-5.5/alsa-hda-realtek-enable-the-headset-of-asus-b9450fa-with-alc294.patch b/queue-5.5/alsa-hda-realtek-enable-the-headset-of-asus-b9450fa-with-alc294.patch
new file mode 100644 (file)
index 0000000..32b72ce
--- /dev/null
@@ -0,0 +1,59 @@
+From 8b33a134a9cc2a501f8fc731d91caef39237d495 Mon Sep 17 00:00:00 2001
+From: Jian-Hong Pan <jian-hong@endlessm.com>
+Date: Tue, 25 Feb 2020 15:29:21 +0800
+Subject: ALSA: hda/realtek - Enable the headset of ASUS B9450FA with ALC294
+
+From: Jian-Hong Pan <jian-hong@endlessm.com>
+
+commit 8b33a134a9cc2a501f8fc731d91caef39237d495 upstream.
+
+A headset on the laptop like ASUS B9450FA does not work, until quirk
+ALC294_FIXUP_ASUS_HPE is applied.
+
+Signed-off-by: Jian-Hong Pan <jian-hong@endlessm.com>
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200225072920.109199-1-jian-hong@endlessm.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5922,6 +5922,7 @@ enum {
+       ALC294_FIXUP_SPK2_TO_DAC1,
+       ALC294_FIXUP_ASUS_DUAL_SPK,
+       ALC285_FIXUP_THINKPAD_HEADSET_JACK,
++      ALC294_FIXUP_ASUS_HPE,
+ };
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -7049,6 +7050,17 @@ static const struct hda_fixup alc269_fix
+               .chained = true,
+               .chain_id = ALC285_FIXUP_SPEAKER2_TO_DAC1
+       },
++      [ALC294_FIXUP_ASUS_HPE] = {
++              .type = HDA_FIXUP_VERBS,
++              .v.verbs = (const struct hda_verb[]) {
++                      /* Set EAPD high */
++                      { 0x20, AC_VERB_SET_COEF_INDEX, 0x0f },
++                      { 0x20, AC_VERB_SET_PROC_COEF, 0x7774 },
++                      { }
++              },
++              .chained = true,
++              .chain_id = ALC294_FIXUP_ASUS_HEADSET_MIC
++      },
+ };
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -7214,6 +7226,7 @@ static const struct snd_pci_quirk alc269
+       SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_DUAL_SPK),
+       SND_PCI_QUIRK(0x1043, 0x18b1, "Asus MJ401TA", ALC256_FIXUP_ASUS_HEADSET_MIC),
++      SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
+       SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
+       SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
+       SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
diff --git a/queue-5.5/alsa-hda-realtek-fix-a-regression-for-mute-led-on-lenovo-carbon-x1.patch b/queue-5.5/alsa-hda-realtek-fix-a-regression-for-mute-led-on-lenovo-carbon-x1.patch
new file mode 100644 (file)
index 0000000..05d913c
--- /dev/null
@@ -0,0 +1,34 @@
+From c37c0ab029569a75fd180edb03d411e7a28a936f Mon Sep 17 00:00:00 2001
+From: Hui Wang <hui.wang@canonical.com>
+Date: Wed, 19 Feb 2020 13:23:06 +0800
+Subject: ALSA: hda/realtek - Fix a regression for mute led on Lenovo Carbon X1
+
+From: Hui Wang <hui.wang@canonical.com>
+
+commit c37c0ab029569a75fd180edb03d411e7a28a936f upstream.
+
+Need to chain the THINKPAD_ACPI, otherwise the mute led will not
+work.
+
+Fixes: d2cd795c4ece ("ALSA: hda - fixup for the bass speaker on Lenovo Carbon X1 7th gen")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Hui Wang <hui.wang@canonical.com>
+Link: https://lore.kernel.org/r/20200219052306.24935-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/patch_realtek.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6684,6 +6684,8 @@ static const struct hda_fixup alc269_fix
+       [ALC285_FIXUP_SPEAKER2_TO_DAC1] = {
+               .type = HDA_FIXUP_FUNC,
+               .v.func = alc285_fixup_speaker2_to_dac1,
++              .chained = true,
++              .chain_id = ALC269_FIXUP_THINKPAD_ACPI
+       },
+       [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
+               .type = HDA_FIXUP_PINS,
diff --git a/queue-5.5/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-master.patch b/queue-5.5/alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-master.patch
new file mode 100644 (file)
index 0000000..f59ea3b
--- /dev/null
@@ -0,0 +1,34 @@
+From 0d45e86d2267d5bdf7bbb631499788da1c27ceb2 Mon Sep 17 00:00:00 2001
+From: Christian Lachner <gladiac@gmail.com>
+Date: Sun, 23 Feb 2020 10:24:16 +0100
+Subject: ALSA: hda/realtek - Fix silent output on Gigabyte X570 Aorus Master
+
+From: Christian Lachner <gladiac@gmail.com>
+
+commit 0d45e86d2267d5bdf7bbb631499788da1c27ceb2 upstream.
+
+The Gigabyte X570 Aorus Master motherboard with ALC1220 codec
+requires a similar workaround for Clevo laptops to enforce the
+DAC/mixer connection path. Set up a quirk entry for that.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205275
+Signed-off-by: Christian Lachner <gladiac@gmail.com>
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200223092416.15016-2-gladiac@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
+@@ -2447,6 +2447,7 @@ static const struct snd_pci_quirk alc882
+       SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
+       SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
+       SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
++      SND_PCI_QUIRK(0x1458, 0xa0cd, "Gigabyte X570 Aorus Master", ALC1220_FIXUP_CLEVO_P950),
+       SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
+       SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
+       SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
diff --git a/queue-5.5/binder-prevent-uaf-for-binderfs-devices-ii.patch b/queue-5.5/binder-prevent-uaf-for-binderfs-devices-ii.patch
new file mode 100644 (file)
index 0000000..f2752ee
--- /dev/null
@@ -0,0 +1,216 @@
+From f0fe2c0f050d31babcad7d65f1d550d462a40064 Mon Sep 17 00:00:00 2001
+From: Christian Brauner <christian.brauner@ubuntu.com>
+Date: Tue, 3 Mar 2020 17:43:40 +0100
+Subject: binder: prevent UAF for binderfs devices II
+
+From: Christian Brauner <christian.brauner@ubuntu.com>
+
+commit f0fe2c0f050d31babcad7d65f1d550d462a40064 upstream.
+
+This is a necessary follow up to the first fix I proposed and we merged
+in 2669b8b0c79 ("binder: prevent UAF for binderfs devices"). I have been
+overly optimistic that the simple fix I proposed would work. But alas,
+ihold() + iput() won't work since the inodes won't survive the
+destruction of the superblock.
+So all we get with my prior fix is a different race with a tinier
+race-window but it doesn't solve the issue. Fwiw, the problem lies with
+generic_shutdown_super(). It even has this cozy Al-style comment:
+
+          if (!list_empty(&sb->s_inodes)) {
+                  printk("VFS: Busy inodes after unmount of %s. "
+                     "Self-destruct in 5 seconds.  Have a nice day...\n",
+                     sb->s_id);
+          }
+
+On binder_release(), binder_defer_work(proc, BINDER_DEFERRED_RELEASE) is
+called which punts the actual cleanup operation to a workqueue. At some
+point, binder_deferred_func() will be called which will end up calling
+binder_deferred_release() which will retrieve and cleanup the
+binder_context attach to this struct binder_proc.
+
+If we trace back where this binder_context is attached to binder_proc we
+see that it is set in binder_open() and is taken from the struct
+binder_device it is associated with. This obviously assumes that the
+struct binder_device that context is attached to is _never_ freed. While
+that might be true for devtmpfs binder devices it is most certainly
+wrong for binderfs binder devices.
+
+So, assume binder_open() is called on a binderfs binder devices. We now
+stash away the struct binder_context associated with that struct
+binder_devices:
+       proc->context = &binder_dev->context;
+       /* binderfs stashes devices in i_private */
+       if (is_binderfs_device(nodp)) {
+               binder_dev = nodp->i_private;
+               info = nodp->i_sb->s_fs_info;
+               binder_binderfs_dir_entry_proc = info->proc_log_dir;
+       } else {
+       .
+       .
+       .
+       proc->context = &binder_dev->context;
+
+Now let's assume that the binderfs instance for that binder devices is
+shutdown via umount() and/or the mount namespace associated with it goes
+away. As long as there is still an fd open for that binderfs binder
+device things are fine. But let's assume we now close the last fd for
+that binderfs binder device. Now binder_release() is called and punts to
+the workqueue. Assume that the workqueue has quite a bit of stuff to do
+and doesn't get to cleaning up the struct binder_proc and the associated
+struct binder_context with it for that binderfs binder device right
+away. In the meantime, the VFS is killing the super block and is
+ultimately calling sb->evict_inode() which means it will call
+binderfs_evict_inode() which does:
+
+static void binderfs_evict_inode(struct inode *inode)
+{
+       struct binder_device *device = inode->i_private;
+       struct binderfs_info *info = BINDERFS_I(inode);
+
+       clear_inode(inode);
+
+       if (!S_ISCHR(inode->i_mode) || !device)
+               return;
+
+       mutex_lock(&binderfs_minors_mutex);
+       --info->device_count;
+       ida_free(&binderfs_minors, device->miscdev.minor);
+       mutex_unlock(&binderfs_minors_mutex);
+
+       kfree(device->context.name);
+       kfree(device);
+}
+
+thereby freeing the struct binder_device including struct
+binder_context.
+
+Now the workqueue finally has time to get around to cleaning up struct
+binder_proc and is now trying to access the associate struct
+binder_context. Since it's already freed it will OOPs.
+
+Fix this by introducing a refounct on binder devices.
+
+This is an alternative fix to 51d8a7eca677 ("binder: prevent UAF read in
+print_binder_transaction_log_entry()").
+
+Fixes: 3ad20fe393b3 ("binder: implement binderfs")
+Fixes: 2669b8b0c798 ("binder: prevent UAF for binderfs devices")
+Fixes: 03e2e07e3814 ("binder: Make transaction_log available in binderfs")
+Related : 51d8a7eca677 ("binder: prevent UAF read in print_binder_transaction_log_entry()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
+Acked-by: Todd Kjos <tkjos@google.com>
+Link: https://lore.kernel.org/r/20200303164340.670054-1-christian.brauner@ubuntu.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/android/binder.c          |   12 +++++++++---
+ drivers/android/binder_internal.h |   15 ++-------------
+ drivers/android/binderfs.c        |    7 +++++--
+ 3 files changed, 16 insertions(+), 18 deletions(-)
+
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -5219,13 +5219,14 @@ static int binder_open(struct inode *nod
+       proc->default_priority = task_nice(current);
+       /* binderfs stashes devices in i_private */
+       if (is_binderfs_device(nodp)) {
+-              binder_dev = binderfs_device_get(nodp->i_private);
++              binder_dev = nodp->i_private;
+               info = nodp->i_sb->s_fs_info;
+               binder_binderfs_dir_entry_proc = info->proc_log_dir;
+       } else {
+               binder_dev = container_of(filp->private_data,
+                                         struct binder_device, miscdev);
+       }
++      refcount_inc(&binder_dev->ref);
+       proc->context = &binder_dev->context;
+       binder_alloc_init(&proc->alloc);
+@@ -5420,6 +5421,12 @@ static void binder_deferred_release(stru
+               context->binder_context_mgr_node = NULL;
+       }
+       mutex_unlock(&context->context_mgr_node_lock);
++      device = container_of(proc->context, struct binder_device, context);
++      if (refcount_dec_and_test(&device->ref)) {
++              kfree(context->name);
++              kfree(device);
++      }
++      proc->context = NULL;
+       binder_inner_proc_lock(proc);
+       /*
+        * Make sure proc stays alive after we
+@@ -5483,8 +5490,6 @@ static void binder_deferred_release(stru
+                    outgoing_refs, active_transactions);
+       binder_proc_dec_tmpref(proc);
+-      device = container_of(proc->context, struct binder_device, context);
+-      binderfs_device_put(device);
+ }
+ static void binder_deferred_func(struct work_struct *work)
+@@ -6078,6 +6083,7 @@ static int __init init_binder_device(con
+       binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;
+       binder_device->miscdev.name = name;
++      refcount_set(&binder_device->ref, 1);
+       binder_device->context.binder_context_mgr_uid = INVALID_UID;
+       binder_device->context.name = name;
+       mutex_init(&binder_device->context.context_mgr_node_lock);
+--- a/drivers/android/binder_internal.h
++++ b/drivers/android/binder_internal.h
+@@ -8,6 +8,7 @@
+ #include <linux/list.h>
+ #include <linux/miscdevice.h>
+ #include <linux/mutex.h>
++#include <linux/refcount.h>
+ #include <linux/stddef.h>
+ #include <linux/types.h>
+ #include <linux/uidgid.h>
+@@ -33,21 +34,9 @@ struct binder_device {
+       struct miscdevice miscdev;
+       struct binder_context context;
+       struct inode *binderfs_inode;
++      refcount_t ref;
+ };
+-static inline struct binder_device *binderfs_device_get(struct binder_device *dev)
+-{
+-      if (dev->binderfs_inode)
+-              ihold(dev->binderfs_inode);
+-      return dev;
+-}
+-
+-static inline void binderfs_device_put(struct binder_device *dev)
+-{
+-      if (dev->binderfs_inode)
+-              iput(dev->binderfs_inode);
+-}
+-
+ /**
+  * binderfs_mount_opts - mount options for binderfs
+  * @max: maximum number of allocatable binderfs binder devices
+--- a/drivers/android/binderfs.c
++++ b/drivers/android/binderfs.c
+@@ -154,6 +154,7 @@ static int binderfs_binder_device_create
+       if (!name)
+               goto err;
++      refcount_set(&device->ref, 1);
+       device->binderfs_inode = inode;
+       device->context.binder_context_mgr_uid = INVALID_UID;
+       device->context.name = name;
+@@ -257,8 +258,10 @@ static void binderfs_evict_inode(struct
+       ida_free(&binderfs_minors, device->miscdev.minor);
+       mutex_unlock(&binderfs_minors_mutex);
+-      kfree(device->context.name);
+-      kfree(device);
++      if (refcount_dec_and_test(&device->ref)) {
++              kfree(device->context.name);
++              kfree(device);
++      }
+ }
+ /**
diff --git a/queue-5.5/binder-prevent-uaf-for-binderfs-devices.patch b/queue-5.5/binder-prevent-uaf-for-binderfs-devices.patch
new file mode 100644 (file)
index 0000000..fd588f1
--- /dev/null
@@ -0,0 +1,147 @@
+From 2669b8b0c798fbe1a31d49e07aa33233d469ad9b Mon Sep 17 00:00:00 2001
+From: Christian Brauner <christian.brauner@ubuntu.com>
+Date: Fri, 21 Feb 2020 19:01:24 +0100
+Subject: binder: prevent UAF for binderfs devices
+
+From: Christian Brauner <christian.brauner@ubuntu.com>
+
+commit 2669b8b0c798fbe1a31d49e07aa33233d469ad9b upstream.
+
+On binder_release(), binder_defer_work(proc, BINDER_DEFERRED_RELEASE) is
+called which punts the actual cleanup operation to a workqueue. At some
+point, binder_deferred_func() will be called which will end up calling
+binder_deferred_release() which will retrieve and cleanup the
+binder_context attach to this struct binder_proc.
+
+If we trace back where this binder_context is attached to binder_proc we
+see that it is set in binder_open() and is taken from the struct
+binder_device it is associated with. This obviously assumes that the
+struct binder_device that context is attached to is _never_ freed. While
+that might be true for devtmpfs binder devices it is most certainly
+wrong for binderfs binder devices.
+
+So, assume binder_open() is called on a binderfs binder devices. We now
+stash away the struct binder_context associated with that struct
+binder_devices:
+       proc->context = &binder_dev->context;
+       /* binderfs stashes devices in i_private */
+       if (is_binderfs_device(nodp)) {
+               binder_dev = nodp->i_private;
+               info = nodp->i_sb->s_fs_info;
+               binder_binderfs_dir_entry_proc = info->proc_log_dir;
+       } else {
+       .
+       .
+       .
+       proc->context = &binder_dev->context;
+
+Now let's assume that the binderfs instance for that binder devices is
+shutdown via umount() and/or the mount namespace associated with it goes
+away. As long as there is still an fd open for that binderfs binder
+device things are fine. But let's assume we now close the last fd for
+that binderfs binder device. Now binder_release() is called and punts to
+the workqueue. Assume that the workqueue has quite a bit of stuff to do
+and doesn't get to cleaning up the struct binder_proc and the associated
+struct binder_context with it for that binderfs binder device right
+away. In the meantime, the VFS is killing the super block and is
+ultimately calling sb->evict_inode() which means it will call
+binderfs_evict_inode() which does:
+
+static void binderfs_evict_inode(struct inode *inode)
+{
+       struct binder_device *device = inode->i_private;
+       struct binderfs_info *info = BINDERFS_I(inode);
+
+       clear_inode(inode);
+
+       if (!S_ISCHR(inode->i_mode) || !device)
+               return;
+
+       mutex_lock(&binderfs_minors_mutex);
+       --info->device_count;
+       ida_free(&binderfs_minors, device->miscdev.minor);
+       mutex_unlock(&binderfs_minors_mutex);
+
+       kfree(device->context.name);
+       kfree(device);
+}
+
+thereby freeing the struct binder_device including struct
+binder_context.
+
+Now the workqueue finally has time to get around to cleaning up struct
+binder_proc and is now trying to access the associate struct
+binder_context. Since it's already freed it will OOPs.
+
+Fix this by holding an additional reference to the inode that is only
+released once the workqueue is done cleaning up struct binder_proc. This
+is an easy alternative to introducing separate refcounting on struct
+binder_device which we can always do later if it becomes necessary.
+
+This is an alternative fix to 51d8a7eca677 ("binder: prevent UAF read in
+print_binder_transaction_log_entry()").
+
+Fixes: 3ad20fe393b3 ("binder: implement binderfs")
+Fixes: 03e2e07e3814 ("binder: Make transaction_log available in binderfs")
+Related : 51d8a7eca677 ("binder: prevent UAF read in print_binder_transaction_log_entry()")
+Cc: stable@vger.kernel.org
+Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
+Acked-by: Todd Kjos <tkjos@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/android/binder.c          |    5 ++++-
+ drivers/android/binder_internal.h |   13 +++++++++++++
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -5219,7 +5219,7 @@ static int binder_open(struct inode *nod
+       proc->default_priority = task_nice(current);
+       /* binderfs stashes devices in i_private */
+       if (is_binderfs_device(nodp)) {
+-              binder_dev = nodp->i_private;
++              binder_dev = binderfs_device_get(nodp->i_private);
+               info = nodp->i_sb->s_fs_info;
+               binder_binderfs_dir_entry_proc = info->proc_log_dir;
+       } else {
+@@ -5403,6 +5403,7 @@ static int binder_node_release(struct bi
+ static void binder_deferred_release(struct binder_proc *proc)
+ {
+       struct binder_context *context = proc->context;
++      struct binder_device *device;
+       struct rb_node *n;
+       int threads, nodes, incoming_refs, outgoing_refs, active_transactions;
+@@ -5482,6 +5483,8 @@ static void binder_deferred_release(stru
+                    outgoing_refs, active_transactions);
+       binder_proc_dec_tmpref(proc);
++      device = container_of(proc->context, struct binder_device, context);
++      binderfs_device_put(device);
+ }
+ static void binder_deferred_func(struct work_struct *work)
+--- a/drivers/android/binder_internal.h
++++ b/drivers/android/binder_internal.h
+@@ -35,6 +35,19 @@ struct binder_device {
+       struct inode *binderfs_inode;
+ };
++static inline struct binder_device *binderfs_device_get(struct binder_device *dev)
++{
++      if (dev->binderfs_inode)
++              ihold(dev->binderfs_inode);
++      return dev;
++}
++
++static inline void binderfs_device_put(struct binder_device *dev)
++{
++      if (dev->binderfs_inode)
++              iput(dev->binderfs_inode);
++}
++
+ /**
+  * binderfs_mount_opts - mount options for binderfs
+  * @max: maximum number of allocatable binderfs binder devices
diff --git a/queue-5.5/cifs-don-t-leak-eagain-for-stat-during-reconnect.patch b/queue-5.5/cifs-don-t-leak-eagain-for-stat-during-reconnect.patch
new file mode 100644 (file)
index 0000000..99b778d
--- /dev/null
@@ -0,0 +1,61 @@
+From fc513fac56e1b626ae48a74d7551d9c35c50129e Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+Date: Wed, 19 Feb 2020 06:01:03 +1000
+Subject: cifs: don't leak -EAGAIN for stat() during reconnect
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+commit fc513fac56e1b626ae48a74d7551d9c35c50129e upstream.
+
+If from cifs_revalidate_dentry_attr() the SMB2/QUERY_INFO call fails with an
+error, such as STATUS_SESSION_EXPIRED, causing the session to be reconnected
+it is possible we will leak -EAGAIN back to the application even for
+system calls such as stat() where this is not a valid error.
+
+Fix this by re-trying the operation from within cifs_revalidate_dentry_attr()
+if cifs_get_inode_info*() returns -EAGAIN.
+
+This fixes stat() and possibly also other system calls that uses
+cifs_revalidate_dentry*().
+
+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Reviewed-by: Aurelien Aptel <aaptel@suse.com>
+CC: Stable <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/inode.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -2074,6 +2074,7 @@ int cifs_revalidate_dentry_attr(struct d
+       struct inode *inode = d_inode(dentry);
+       struct super_block *sb = dentry->d_sb;
+       char *full_path = NULL;
++      int count = 0;
+       if (inode == NULL)
+               return -ENOENT;
+@@ -2095,15 +2096,18 @@ int cifs_revalidate_dentry_attr(struct d
+                full_path, inode, inode->i_count.counter,
+                dentry, cifs_get_time(dentry), jiffies);
++again:
+       if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
+               rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
+       else
+               rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
+                                        xid, NULL);
+-
++      if (rc == -EAGAIN && count++ < 10)
++              goto again;
+ out:
+       kfree(full_path);
+       free_xid(xid);
++
+       return rc;
+ }
diff --git a/queue-5.5/cifs-fix-rename-by-ensuring-source-handle-opened-with-delete-bit.patch b/queue-5.5/cifs-fix-rename-by-ensuring-source-handle-opened-with-delete-bit.patch
new file mode 100644 (file)
index 0000000..8ca2996
--- /dev/null
@@ -0,0 +1,312 @@
+From 86f740f2aed5ea7fe1aa86dc2df0fb4ab0f71088 Mon Sep 17 00:00:00 2001
+From: Aurelien Aptel <aaptel@suse.com>
+Date: Fri, 21 Feb 2020 11:19:06 +0100
+Subject: cifs: fix rename() by ensuring source handle opened with DELETE bit
+
+From: Aurelien Aptel <aaptel@suse.com>
+
+commit 86f740f2aed5ea7fe1aa86dc2df0fb4ab0f71088 upstream.
+
+To rename a file in SMB2 we open it with the DELETE access and do a
+special SetInfo on it. If the handle is missing the DELETE bit the
+server will fail the SetInfo with STATUS_ACCESS_DENIED.
+
+We currently try to reuse any existing opened handle we have with
+cifs_get_writable_path(). That function looks for handles with WRITE
+access but doesn't check for DELETE, making rename() fail if it finds
+a handle to reuse. Simple reproducer below.
+
+To select handles with the DELETE bit, this patch adds a flag argument
+to cifs_get_writable_path() and find_writable_file() and the existing
+'bool fsuid_only' argument is converted to a flag.
+
+The cifsFileInfo struct only stores the UNIX open mode but not the
+original SMB access flags. Since the DELETE bit is not mapped in that
+mode, this patch stores the access mask in cifs_fid on file open,
+which is accessible from cifsFileInfo.
+
+Simple reproducer:
+
+       #include <stdio.h>
+       #include <stdlib.h>
+       #include <sys/types.h>
+       #include <sys/stat.h>
+       #include <fcntl.h>
+       #include <unistd.h>
+       #define E(s) perror(s), exit(1)
+
+       int main(int argc, char *argv[])
+       {
+               int fd, ret;
+               if (argc != 3) {
+                       fprintf(stderr, "Usage: %s A B\n"
+                       "create&open A in write mode, "
+                       "rename A to B, close A\n", argv[0]);
+                       return 0;
+               }
+
+               fd = openat(AT_FDCWD, argv[1], O_WRONLY|O_CREAT|O_SYNC, 0666);
+               if (fd == -1) E("openat()");
+
+               ret = rename(argv[1], argv[2]);
+               if (ret) E("rename()");
+
+               ret = close(fd);
+               if (ret) E("close()");
+
+               return ret;
+       }
+
+$ gcc -o bugrename bugrename.c
+$ ./bugrename /mnt/a /mnt/b
+rename(): Permission denied
+
+Fixes: 8de9e86c67ba ("cifs: create a helper to find a writeable handle by path name")
+CC: Stable <stable@vger.kernel.org>
+Signed-off-by: Aurelien Aptel <aaptel@suse.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsglob.h  |    7 +++++++
+ fs/cifs/cifsproto.h |    5 +++--
+ fs/cifs/cifssmb.c   |    3 ++-
+ fs/cifs/file.c      |   19 ++++++++++++-------
+ fs/cifs/inode.c     |    6 +++---
+ fs/cifs/smb1ops.c   |    2 +-
+ fs/cifs/smb2inode.c |    4 ++--
+ fs/cifs/smb2ops.c   |    3 ++-
+ fs/cifs/smb2pdu.c   |    1 +
+ 9 files changed, 33 insertions(+), 17 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -1277,6 +1277,7 @@ struct cifs_fid {
+       __u64 volatile_fid;     /* volatile file id for smb2 */
+       __u8 lease_key[SMB2_LEASE_KEY_SIZE];    /* lease key for smb2 */
+       __u8 create_guid[16];
++      __u32 access;
+       struct cifs_pending_open *pending_open;
+       unsigned int epoch;
+ #ifdef CONFIG_CIFS_DEBUG2
+@@ -1737,6 +1738,12 @@ static inline bool is_retryable_error(in
+       return false;
+ }
++
++/* cifs_get_writable_file() flags */
++#define FIND_WR_ANY         0
++#define FIND_WR_FSUID_ONLY  1
++#define FIND_WR_WITH_DELETE 2
++
+ #define   MID_FREE 0
+ #define   MID_REQUEST_ALLOCATED 1
+ #define   MID_REQUEST_SUBMITTED 2
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -134,11 +134,12 @@ extern bool backup_cred(struct cifs_sb_i
+ extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
+ extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
+                           unsigned int bytes_written);
+-extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
++extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
+ extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
+-                                bool fsuid_only,
++                                int flags,
+                                 struct cifsFileInfo **ret_file);
+ extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
++                                int flags,
+                                 struct cifsFileInfo **ret_file);
+ extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
+ extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -1492,6 +1492,7 @@ openRetry:
+       *oplock = rsp->OplockLevel;
+       /* cifs fid stays in le */
+       oparms->fid->netfid = rsp->Fid;
++      oparms->fid->access = desired_access;
+       /* Let caller know file was created so we can set the mode. */
+       /* Do we care about the CreateAction in any other cases? */
+@@ -2115,7 +2116,7 @@ cifs_writev_requeue(struct cifs_writedat
+               wdata2->tailsz = tailsz;
+               wdata2->bytes = cur_len;
+-              rc = cifs_get_writable_file(CIFS_I(inode), false,
++              rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY,
+                                           &wdata2->cfile);
+               if (!wdata2->cfile) {
+                       cifs_dbg(VFS, "No writable handle to retry writepages rc=%d\n",
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -1964,7 +1964,7 @@ struct cifsFileInfo *find_readable_file(
+ /* Return -EBADF if no handle is found and general rc otherwise */
+ int
+-cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only,
++cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags,
+                      struct cifsFileInfo **ret_file)
+ {
+       struct cifsFileInfo *open_file, *inv_file = NULL;
+@@ -1972,7 +1972,8 @@ cifs_get_writable_file(struct cifsInodeI
+       bool any_available = false;
+       int rc = -EBADF;
+       unsigned int refind = 0;
+-
++      bool fsuid_only = flags & FIND_WR_FSUID_ONLY;
++      bool with_delete = flags & FIND_WR_WITH_DELETE;
+       *ret_file = NULL;
+       /*
+@@ -2004,6 +2005,8 @@ refind_writable:
+                       continue;
+               if (fsuid_only && !uid_eq(open_file->uid, current_fsuid()))
+                       continue;
++              if (with_delete && !(open_file->fid.access & DELETE))
++                      continue;
+               if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
+                       if (!open_file->invalidHandle) {
+                               /* found a good writable file */
+@@ -2051,12 +2054,12 @@ refind_writable:
+ }
+ struct cifsFileInfo *
+-find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only)
++find_writable_file(struct cifsInodeInfo *cifs_inode, int flags)
+ {
+       struct cifsFileInfo *cfile;
+       int rc;
+-      rc = cifs_get_writable_file(cifs_inode, fsuid_only, &cfile);
++      rc = cifs_get_writable_file(cifs_inode, flags, &cfile);
+       if (rc)
+               cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc);
+@@ -2065,6 +2068,7 @@ find_writable_file(struct cifsInodeInfo
+ int
+ cifs_get_writable_path(struct cifs_tcon *tcon, const char *name,
++                     int flags,
+                      struct cifsFileInfo **ret_file)
+ {
+       struct list_head *tmp;
+@@ -2091,7 +2095,7 @@ cifs_get_writable_path(struct cifs_tcon
+               kfree(full_path);
+               cinode = CIFS_I(d_inode(cfile->dentry));
+               spin_unlock(&tcon->open_file_lock);
+-              return cifs_get_writable_file(cinode, 0, ret_file);
++              return cifs_get_writable_file(cinode, flags, ret_file);
+       }
+       spin_unlock(&tcon->open_file_lock);
+@@ -2168,7 +2172,8 @@ static int cifs_partialpagewrite(struct
+       if (mapping->host->i_size - offset < (loff_t)to)
+               to = (unsigned)(mapping->host->i_size - offset);
+-      rc = cifs_get_writable_file(CIFS_I(mapping->host), false, &open_file);
++      rc = cifs_get_writable_file(CIFS_I(mapping->host), FIND_WR_ANY,
++                                  &open_file);
+       if (!rc) {
+               bytes_written = cifs_write(open_file, open_file->pid,
+                                          write_data, to - from, &offset);
+@@ -2361,7 +2366,7 @@ retry:
+               if (cfile)
+                       cifsFileInfo_put(cfile);
+-              rc = cifs_get_writable_file(CIFS_I(inode), false, &cfile);
++              rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, &cfile);
+               /* in case of an error store it to return later */
+               if (rc)
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -2283,7 +2283,7 @@ cifs_set_file_size(struct inode *inode,
+        * writebehind data than the SMB timeout for the SetPathInfo
+        * request would allow
+        */
+-      open_file = find_writable_file(cifsInode, true);
++      open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY);
+       if (open_file) {
+               tcon = tlink_tcon(open_file->tlink);
+               server = tcon->ses->server;
+@@ -2433,7 +2433,7 @@ cifs_setattr_unix(struct dentry *direntr
+               args->ctime = NO_CHANGE_64;
+       args->device = 0;
+-      open_file = find_writable_file(cifsInode, true);
++      open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY);
+       if (open_file) {
+               u16 nfid = open_file->fid.netfid;
+               u32 npid = open_file->pid;
+@@ -2536,7 +2536,7 @@ cifs_setattr_nounix(struct dentry *diren
+       rc = 0;
+       if (attrs->ia_valid & ATTR_MTIME) {
+-              rc = cifs_get_writable_file(cifsInode, false, &wfile);
++              rc = cifs_get_writable_file(cifsInode, FIND_WR_ANY, &wfile);
+               if (!rc) {
+                       tcon = tlink_tcon(wfile->tlink);
+                       rc = tcon->ses->server->ops->flush(xid, tcon, &wfile->fid);
+--- a/fs/cifs/smb1ops.c
++++ b/fs/cifs/smb1ops.c
+@@ -765,7 +765,7 @@ smb_set_file_info(struct inode *inode, c
+       struct cifs_tcon *tcon;
+       /* if the file is already open for write, just use that fileid */
+-      open_file = find_writable_file(cinode, true);
++      open_file = find_writable_file(cinode, FIND_WR_FSUID_ONLY);
+       if (open_file) {
+               fid.netfid = open_file->fid.netfid;
+               netpid = open_file->pid;
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -526,7 +526,7 @@ smb2_mkdir_setinfo(struct inode *inode,
+       cifs_i = CIFS_I(inode);
+       dosattrs = cifs_i->cifsAttrs | ATTR_READONLY;
+       data.Attributes = cpu_to_le32(dosattrs);
+-      cifs_get_writable_path(tcon, name, &cfile);
++      cifs_get_writable_path(tcon, name, FIND_WR_ANY, &cfile);
+       tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
+                                FILE_WRITE_ATTRIBUTES, FILE_CREATE,
+                                CREATE_NOT_FILE, ACL_NO_MODE,
+@@ -582,7 +582,7 @@ smb2_rename_path(const unsigned int xid,
+ {
+       struct cifsFileInfo *cfile;
+-      cifs_get_writable_path(tcon, from_name, &cfile);
++      cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile);
+       return smb2_set_path_attr(xid, tcon, from_name, to_name,
+                                 cifs_sb, DELETE, SMB2_OP_RENAME, cfile);
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -1366,6 +1366,7 @@ smb2_set_fid(struct cifsFileInfo *cfile,
+       cfile->fid.persistent_fid = fid->persistent_fid;
+       cfile->fid.volatile_fid = fid->volatile_fid;
++      cfile->fid.access = fid->access;
+ #ifdef CONFIG_CIFS_DEBUG2
+       cfile->fid.mid = fid->mid;
+ #endif /* CIFS_DEBUG2 */
+@@ -3225,7 +3226,7 @@ static loff_t smb3_llseek(struct file *f
+        * some servers (Windows2016) will not reflect recent writes in
+        * QUERY_ALLOCATED_RANGES until SMB2_flush is called.
+        */
+-      wrcfile = find_writable_file(cifsi, false);
++      wrcfile = find_writable_file(cifsi, FIND_WR_ANY);
+       if (wrcfile) {
+               filemap_write_and_wait(inode->i_mapping);
+               smb2_flush_file(xid, tcon, &wrcfile->fid);
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -2749,6 +2749,7 @@ SMB2_open(const unsigned int xid, struct
+       atomic_inc(&tcon->num_remote_opens);
+       oparms->fid->persistent_fid = rsp->PersistentFileId;
+       oparms->fid->volatile_fid = rsp->VolatileFileId;
++      oparms->fid->access = oparms->desired_access;
+ #ifdef CONFIG_CIFS_DEBUG2
+       oparms->fid->mid = le64_to_cpu(rsp->sync_hdr.MessageId);
+ #endif /* CIFS_DEBUG2 */
diff --git a/queue-5.5/driver-core-call-sync_state-even-if-supplier-has-no-consumers.patch b/queue-5.5/driver-core-call-sync_state-even-if-supplier-has-no-consumers.patch
new file mode 100644 (file)
index 0000000..dace13d
--- /dev/null
@@ -0,0 +1,94 @@
+From 21eb93f432b1a785df193df1a56a59e9eb3a985f Mon Sep 17 00:00:00 2001
+From: Saravana Kannan <saravanak@google.com>
+Date: Fri, 21 Feb 2020 00:05:08 -0800
+Subject: driver core: Call sync_state() even if supplier has no consumers
+
+From: Saravana Kannan <saravanak@google.com>
+
+commit 21eb93f432b1a785df193df1a56a59e9eb3a985f upstream.
+
+The initial patch that added sync_state() support didn't handle the case
+where a supplier has no consumers. This was because when a device is
+successfully bound with a driver, only its suppliers were checked to see
+if they are eligible to get a sync_state(). This is not sufficient for
+devices that have no consumers but still need to do device state clean
+up. So fix this.
+
+Fixes: fc5a251d0fd7ca90 (driver core: Add sync_state driver/bus callback)
+Signed-off-by: Saravana Kannan <saravanak@google.com>
+Cc: stable <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200221080510.197337-2-saravanak@google.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/base/core.c |   23 +++++++++++++++++------
+ 1 file changed, 17 insertions(+), 6 deletions(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -745,25 +745,31 @@ static void __device_links_queue_sync_st
+ /**
+  * device_links_flush_sync_list - Call sync_state() on a list of devices
+  * @list: List of devices to call sync_state() on
++ * @dont_lock_dev: Device for which lock is already held by the caller
+  *
+  * Calls sync_state() on all the devices that have been queued for it. This
+- * function is used in conjunction with __device_links_queue_sync_state().
++ * function is used in conjunction with __device_links_queue_sync_state(). The
++ * @dont_lock_dev parameter is useful when this function is called from a
++ * context where a device lock is already held.
+  */
+-static void device_links_flush_sync_list(struct list_head *list)
++static void device_links_flush_sync_list(struct list_head *list,
++                                       struct device *dont_lock_dev)
+ {
+       struct device *dev, *tmp;
+       list_for_each_entry_safe(dev, tmp, list, links.defer_sync) {
+               list_del_init(&dev->links.defer_sync);
+-              device_lock(dev);
++              if (dev != dont_lock_dev)
++                      device_lock(dev);
+               if (dev->bus->sync_state)
+                       dev->bus->sync_state(dev);
+               else if (dev->driver && dev->driver->sync_state)
+                       dev->driver->sync_state(dev);
+-              device_unlock(dev);
++              if (dev != dont_lock_dev)
++                      device_unlock(dev);
+               put_device(dev);
+       }
+@@ -801,7 +807,7 @@ void device_links_supplier_sync_state_re
+ out:
+       device_links_write_unlock();
+-      device_links_flush_sync_list(&sync_list);
++      device_links_flush_sync_list(&sync_list, NULL);
+ }
+ static int sync_state_resume_initcall(void)
+@@ -865,6 +871,11 @@ void device_links_driver_bound(struct de
+                       driver_deferred_probe_add(link->consumer);
+       }
++      if (defer_sync_state_count)
++              __device_links_supplier_defer_sync(dev);
++      else
++              __device_links_queue_sync_state(dev, &sync_list);
++
+       list_for_each_entry(link, &dev->links.suppliers, c_node) {
+               if (!(link->flags & DL_FLAG_MANAGED))
+                       continue;
+@@ -883,7 +894,7 @@ void device_links_driver_bound(struct de
+       device_links_write_unlock();
+-      device_links_flush_sync_list(&sync_list);
++      device_links_flush_sync_list(&sync_list, dev);
+ }
+ static void device_link_drop_managed(struct device_link *link)
diff --git a/queue-5.5/firmware-imx-scu-ensure-sequential-tx.patch b/queue-5.5/firmware-imx-scu-ensure-sequential-tx.patch
new file mode 100644 (file)
index 0000000..957ea4d
--- /dev/null
@@ -0,0 +1,85 @@
+From 26d0fba29c96241de8a9d16f045b1de49875884c Mon Sep 17 00:00:00 2001
+From: Leonard Crestez <leonard.crestez@nxp.com>
+Date: Thu, 20 Feb 2020 18:10:01 +0200
+Subject: firmware: imx: scu: Ensure sequential TX
+
+From: Leonard Crestez <leonard.crestez@nxp.com>
+
+commit 26d0fba29c96241de8a9d16f045b1de49875884c upstream.
+
+SCU requires that all messages words are written sequentially but linux MU
+driver implements multiple independent channels for each register so ordering
+between different channels must be ensured by SCU API interface.
+
+Wait for tx_done before every send to ensure that no queueing happens at the
+mailbox channel level.
+
+Fixes: edbee095fafb ("firmware: imx: add SCU firmware driver support")
+Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com>
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Peng Fan <peng.fan@nxp.com>
+Reviewed-by:: Oleksij Rempel <o.rempel@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/imx/imx-scu.c |   27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+--- a/drivers/firmware/imx/imx-scu.c
++++ b/drivers/firmware/imx/imx-scu.c
+@@ -29,6 +29,7 @@ struct imx_sc_chan {
+       struct mbox_client cl;
+       struct mbox_chan *ch;
+       int idx;
++      struct completion tx_done;
+ };
+ struct imx_sc_ipc {
+@@ -100,6 +101,14 @@ int imx_scu_get_handle(struct imx_sc_ipc
+ }
+ EXPORT_SYMBOL(imx_scu_get_handle);
++/* Callback called when the word of a message is ack-ed, eg read by SCU */
++static void imx_scu_tx_done(struct mbox_client *cl, void *mssg, int r)
++{
++      struct imx_sc_chan *sc_chan = container_of(cl, struct imx_sc_chan, cl);
++
++      complete(&sc_chan->tx_done);
++}
++
+ static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
+ {
+       struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl);
+@@ -149,6 +158,19 @@ static int imx_scu_ipc_write(struct imx_
+       for (i = 0; i < hdr->size; i++) {
+               sc_chan = &sc_ipc->chans[i % 4];
++
++              /*
++               * SCU requires that all messages words are written
++               * sequentially but linux MU driver implements multiple
++               * independent channels for each register so ordering between
++               * different channels must be ensured by SCU API interface.
++               *
++               * Wait for tx_done before every send to ensure that no
++               * queueing happens at the mailbox channel level.
++               */
++              wait_for_completion(&sc_chan->tx_done);
++              reinit_completion(&sc_chan->tx_done);
++
+               ret = mbox_send_message(sc_chan->ch, &data[i]);
+               if (ret < 0)
+                       return ret;
+@@ -247,6 +269,11 @@ static int imx_scu_probe(struct platform
+               cl->knows_txdone = true;
+               cl->rx_callback = imx_scu_rx_callback;
++              /* Initial tx_done completion as "done" */
++              cl->tx_done = imx_scu_tx_done;
++              init_completion(&sc_chan->tx_done);
++              complete(&sc_chan->tx_done);
++
+               sc_chan->sc_ipc = sc_ipc;
+               sc_chan->idx = i % 4;
+               sc_chan->ch = mbox_request_channel_byname(cl, chan_name);
index c521fbe6a771e21daab53810d6008538c7454354..22c88a62a38f087e521fcd29885d580a0301be06 100644 (file)
@@ -55,3 +55,14 @@ csky-fixup-ftrace-modify-panic.patch
 csky-fixup-compile-warning-for-three-unimplemented-s.patch
 arch-csky-fix-some-kconfig-typos.patch
 selftests-forwarding-vxlan_bridge_1d-use-more-proper.patch
+firmware-imx-scu-ensure-sequential-tx.patch
+binder-prevent-uaf-for-binderfs-devices.patch
+binder-prevent-uaf-for-binderfs-devices-ii.patch
+alsa-hda-realtek-add-headset-mic-supported.patch
+alsa-hda-realtek-add-headset-button-supported-for-thinkpad-x1.patch
+alsa-hda-realtek-fix-a-regression-for-mute-led-on-lenovo-carbon-x1.patch
+alsa-hda-realtek-fix-silent-output-on-gigabyte-x570-aorus-master.patch
+alsa-hda-realtek-enable-the-headset-of-asus-b9450fa-with-alc294.patch
+driver-core-call-sync_state-even-if-supplier-has-no-consumers.patch
+cifs-don-t-leak-eagain-for-stat-during-reconnect.patch
+cifs-fix-rename-by-ensuring-source-handle-opened-with-delete-bit.patch