]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 Jul 2020 12:41:01 +0000 (14:41 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 26 Jul 2020 12:41:01 +0000 (14:41 +0200)
added patches:
alsa-info-drop-warn_on-from-buffer-null-sanity-check.patch
asoc-rt5670-correct-rt5670_ldo_sel_mask.patch
btrfs-fix-double-free-on-ulist-after-backref-resolution-failure.patch
btrfs-fix-mount-failure-caused-by-race-with-umount.patch
btrfs-fix-page-leaks-after-failure-to-lock-page-for-delalloc.patch
btrfs-qgroup-fix-data-leak-caused-by-race-between-writeback-and-truncate.patch
uprobes-change-handle_swbp-to-send-sigtrap-with-si_code-si_kernel-to-fix-gdb-regression.patch

queue-4.14/alsa-info-drop-warn_on-from-buffer-null-sanity-check.patch [new file with mode: 0644]
queue-4.14/asoc-rt5670-correct-rt5670_ldo_sel_mask.patch [new file with mode: 0644]
queue-4.14/btrfs-fix-double-free-on-ulist-after-backref-resolution-failure.patch [new file with mode: 0644]
queue-4.14/btrfs-fix-mount-failure-caused-by-race-with-umount.patch [new file with mode: 0644]
queue-4.14/btrfs-fix-page-leaks-after-failure-to-lock-page-for-delalloc.patch [new file with mode: 0644]
queue-4.14/btrfs-qgroup-fix-data-leak-caused-by-race-between-writeback-and-truncate.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/uprobes-change-handle_swbp-to-send-sigtrap-with-si_code-si_kernel-to-fix-gdb-regression.patch [new file with mode: 0644]

diff --git a/queue-4.14/alsa-info-drop-warn_on-from-buffer-null-sanity-check.patch b/queue-4.14/alsa-info-drop-warn_on-from-buffer-null-sanity-check.patch
new file mode 100644 (file)
index 0000000..0660c31
--- /dev/null
@@ -0,0 +1,43 @@
+From 60379ba08532eca861e933b389526a4dc89e0c42 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 17 Jul 2020 10:40:23 +0200
+Subject: ALSA: info: Drop WARN_ON() from buffer NULL sanity check
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 60379ba08532eca861e933b389526a4dc89e0c42 upstream.
+
+snd_info_get_line() has a sanity check of NULL buffer -- both buffer
+itself being NULL and buffer->buffer being NULL.  Basically both
+checks are valid and necessary, but the problem is that it's with
+snd_BUG_ON() macro that triggers WARN_ON().  The latter condition
+(NULL buffer->buffer) can be met arbitrarily by user since the buffer
+is allocated at the first write, so it means that user can trigger
+WARN_ON() at will.
+
+This patch addresses it by simply moving buffer->buffer NULL check out
+of snd_BUG_ON() so that spurious WARNING is no longer triggered.
+
+Reported-by: syzbot+e42d0746c3c3699b6061@syzkaller.appspotmail.com
+Cc: <stable@vger.kernel.org>
+Link: https://lore.kernel.org/r/20200717084023.5928-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/info.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/sound/core/info.c
++++ b/sound/core/info.c
+@@ -634,7 +634,9 @@ int snd_info_get_line(struct snd_info_bu
+ {
+       int c = -1;
+-      if (snd_BUG_ON(!buffer || !buffer->buffer))
++      if (snd_BUG_ON(!buffer))
++              return 1;
++      if (!buffer->buffer)
+               return 1;
+       if (len <= 0 || buffer->stop || buffer->error)
+               return 1;
diff --git a/queue-4.14/asoc-rt5670-correct-rt5670_ldo_sel_mask.patch b/queue-4.14/asoc-rt5670-correct-rt5670_ldo_sel_mask.patch
new file mode 100644 (file)
index 0000000..9d998d5
--- /dev/null
@@ -0,0 +1,42 @@
+From 5cacc6f5764e94fa753b2c1f5f7f1f3f74286e82 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Sun, 28 Jun 2020 17:52:27 +0200
+Subject: ASoC: rt5670: Correct RT5670_LDO_SEL_MASK
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 5cacc6f5764e94fa753b2c1f5f7f1f3f74286e82 upstream.
+
+The RT5670_PWR_ANLG1 register has 3 bits to select the LDO voltage,
+so the correct mask is 0x7 not 0x3.
+
+Because of this wrong mask we were programming the ldo bits
+to a setting of binary 001 (0x05 & 0x03) instead of binary 101
+when moving to SND_SOC_BIAS_PREPARE.
+
+According to the datasheet 001 is a reserved value, so no idea
+what it did, since the driver was working fine before I guess we
+got lucky and it does something which is ok.
+
+Fixes: 5e8351de740d ("ASoC: add RT5670 CODEC driver")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200628155231.71089-3-hdegoede@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/soc/codecs/rt5670.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/sound/soc/codecs/rt5670.h
++++ b/sound/soc/codecs/rt5670.h
+@@ -760,7 +760,7 @@
+ #define RT5670_PWR_VREF2_BIT                  4
+ #define RT5670_PWR_FV2                                (0x1 << 3)
+ #define RT5670_PWR_FV2_BIT                    3
+-#define RT5670_LDO_SEL_MASK                   (0x3)
++#define RT5670_LDO_SEL_MASK                   (0x7)
+ #define RT5670_LDO_SEL_SFT                    0
+ /* Power Management for Analog 2 (0x64) */
diff --git a/queue-4.14/btrfs-fix-double-free-on-ulist-after-backref-resolution-failure.patch b/queue-4.14/btrfs-fix-double-free-on-ulist-after-backref-resolution-failure.patch
new file mode 100644 (file)
index 0000000..e5bbabd
--- /dev/null
@@ -0,0 +1,159 @@
+From 580c079b5766ac706f56eec5c79aee4bf929fef6 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Mon, 13 Jul 2020 15:11:56 +0100
+Subject: btrfs: fix double free on ulist after backref resolution failure
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 580c079b5766ac706f56eec5c79aee4bf929fef6 upstream.
+
+At btrfs_find_all_roots_safe() we allocate a ulist and set the **roots
+argument to point to it. However if later we fail due to an error returned
+by find_parent_nodes(), we free that ulist but leave a dangling pointer in
+the **roots argument. Upon receiving the error, a caller of this function
+can attempt to free the same ulist again, resulting in an invalid memory
+access.
+
+One such scenario is during qgroup accounting:
+
+btrfs_qgroup_account_extents()
+
+ --> calls btrfs_find_all_roots() passes &new_roots (a stack allocated
+     pointer) to btrfs_find_all_roots()
+
+   --> btrfs_find_all_roots() just calls btrfs_find_all_roots_safe()
+       passing &new_roots to it
+
+     --> allocates ulist and assigns its address to **roots (which
+         points to new_roots from btrfs_qgroup_account_extents())
+
+     --> find_parent_nodes() returns an error, so we free the ulist
+         and leave **roots pointing to it after returning
+
+ --> btrfs_qgroup_account_extents() sees btrfs_find_all_roots() returned
+     an error and jumps to the label 'cleanup', which just tries to
+     free again the same ulist
+
+Stack trace example:
+
+ ------------[ cut here ]------------
+ BTRFS: tree first key check failed
+ WARNING: CPU: 1 PID: 1763215 at fs/btrfs/disk-io.c:422 btrfs_verify_level_key+0xe0/0x180 [btrfs]
+ Modules linked in: dm_snapshot dm_thin_pool (...)
+ CPU: 1 PID: 1763215 Comm: fsstress Tainted: G        W         5.8.0-rc3-btrfs-next-64 #1
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+ RIP: 0010:btrfs_verify_level_key+0xe0/0x180 [btrfs]
+ Code: 28 5b 5d (...)
+ RSP: 0018:ffffb89b473779a0 EFLAGS: 00010286
+ RAX: 0000000000000000 RBX: ffff90397759bf08 RCX: 0000000000000000
+ RDX: 0000000000000001 RSI: 0000000000000027 RDI: 00000000ffffffff
+ RBP: ffff9039a419c000 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: ffffb89b43301000 R12: 000000000000005e
+ R13: ffffb89b47377a2e R14: ffffb89b473779af R15: 0000000000000000
+ FS:  00007fc47e1e1000(0000) GS:ffff9039ac200000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007fc47e1df000 CR3: 00000003d9e4e001 CR4: 00000000003606e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+  read_block_for_search+0xf6/0x350 [btrfs]
+  btrfs_next_old_leaf+0x242/0x650 [btrfs]
+  resolve_indirect_refs+0x7cf/0x9e0 [btrfs]
+  find_parent_nodes+0x4ea/0x12c0 [btrfs]
+  btrfs_find_all_roots_safe+0xbf/0x130 [btrfs]
+  btrfs_qgroup_account_extents+0x9d/0x390 [btrfs]
+  btrfs_commit_transaction+0x4f7/0xb20 [btrfs]
+  btrfs_sync_file+0x3d4/0x4d0 [btrfs]
+  do_fsync+0x38/0x70
+  __x64_sys_fdatasync+0x13/0x20
+  do_syscall_64+0x5c/0xe0
+  entry_SYSCALL_64_after_hwframe+0x44/0xa9
+ RIP: 0033:0x7fc47e2d72e3
+ Code: Bad RIP value.
+ RSP: 002b:00007fffa32098c8 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
+ RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fc47e2d72e3
+ RDX: 00007fffa3209830 RSI: 00007fffa3209830 RDI: 0000000000000003
+ RBP: 000000000000072e R08: 0000000000000001 R09: 0000000000000003
+ R10: 0000000000000000 R11: 0000000000000246 R12: 00000000000003e8
+ R13: 0000000051eb851f R14: 00007fffa3209970 R15: 00005607c4ac8b50
+ irq event stamp: 0
+ hardirqs last  enabled at (0): [<0000000000000000>] 0x0
+ hardirqs last disabled at (0): [<ffffffffb8eb5e85>] copy_process+0x755/0x1eb0
+ softirqs last  enabled at (0): [<ffffffffb8eb5e85>] copy_process+0x755/0x1eb0
+ softirqs last disabled at (0): [<0000000000000000>] 0x0
+ ---[ end trace 8639237550317b48 ]---
+ BTRFS error (device sdc): tree first key mismatch detected, bytenr=62324736 parent_transid=94 key expected=(262,108,1351680) has=(259,108,1921024)
+ general protection fault, probably for non-canonical address 0x6b6b6b6b6b6b6b6b: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC PTI
+ CPU: 2 PID: 1763215 Comm: fsstress Tainted: G        W         5.8.0-rc3-btrfs-next-64 #1
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014
+ RIP: 0010:ulist_release+0x14/0x60 [btrfs]
+ Code: c7 07 00 (...)
+ RSP: 0018:ffffb89b47377d60 EFLAGS: 00010282
+ RAX: 6b6b6b6b6b6b6b6b RBX: ffff903959b56b90 RCX: 0000000000000000
+ RDX: 0000000000000001 RSI: 0000000000270024 RDI: ffff9036e2adc840
+ RBP: ffff9036e2adc848 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000000 R12: ffff9036e2adc840
+ R13: 0000000000000015 R14: ffff9039a419ccf8 R15: ffff90395d605840
+ FS:  00007fc47e1e1000(0000) GS:ffff9039ac600000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f8c1c0a51c8 CR3: 00000003d9e4e004 CR4: 00000000003606e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+  ulist_free+0x13/0x20 [btrfs]
+  btrfs_qgroup_account_extents+0xf3/0x390 [btrfs]
+  btrfs_commit_transaction+0x4f7/0xb20 [btrfs]
+  btrfs_sync_file+0x3d4/0x4d0 [btrfs]
+  do_fsync+0x38/0x70
+  __x64_sys_fdatasync+0x13/0x20
+  do_syscall_64+0x5c/0xe0
+  entry_SYSCALL_64_after_hwframe+0x44/0xa9
+ RIP: 0033:0x7fc47e2d72e3
+ Code: Bad RIP value.
+ RSP: 002b:00007fffa32098c8 EFLAGS: 00000246 ORIG_RAX: 000000000000004b
+ RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fc47e2d72e3
+ RDX: 00007fffa3209830 RSI: 00007fffa3209830 RDI: 0000000000000003
+ RBP: 000000000000072e R08: 0000000000000001 R09: 0000000000000003
+ R10: 0000000000000000 R11: 0000000000000246 R12: 00000000000003e8
+ R13: 0000000051eb851f R14: 00007fffa3209970 R15: 00005607c4ac8b50
+ Modules linked in: dm_snapshot dm_thin_pool (...)
+ ---[ end trace 8639237550317b49 ]---
+ RIP: 0010:ulist_release+0x14/0x60 [btrfs]
+ Code: c7 07 00 (...)
+ RSP: 0018:ffffb89b47377d60 EFLAGS: 00010282
+ RAX: 6b6b6b6b6b6b6b6b RBX: ffff903959b56b90 RCX: 0000000000000000
+ RDX: 0000000000000001 RSI: 0000000000270024 RDI: ffff9036e2adc840
+ RBP: ffff9036e2adc848 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000000 R12: ffff9036e2adc840
+ R13: 0000000000000015 R14: ffff9039a419ccf8 R15: ffff90395d605840
+ FS:  00007fc47e1e1000(0000) GS:ffff9039ad200000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f6a776f7d40 CR3: 00000003d9e4e002 CR4: 00000000003606e0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+
+Fix this by making btrfs_find_all_roots_safe() set *roots to NULL after
+it frees the ulist.
+
+Fixes: 8da6d5815c592b ("Btrfs: added btrfs_find_all_roots()")
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/backref.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -1420,6 +1420,7 @@ static int btrfs_find_all_roots_safe(str
+               if (ret < 0 && ret != -ENOENT) {
+                       ulist_free(tmp);
+                       ulist_free(*roots);
++                      *roots = NULL;
+                       return ret;
+               }
+               node = ulist_next(tmp, &uiter);
diff --git a/queue-4.14/btrfs-fix-mount-failure-caused-by-race-with-umount.patch b/queue-4.14/btrfs-fix-mount-failure-caused-by-race-with-umount.patch
new file mode 100644 (file)
index 0000000..80ca821
--- /dev/null
@@ -0,0 +1,104 @@
+From 48cfa61b58a1fee0bc49eef04f8ccf31493b7cdd Mon Sep 17 00:00:00 2001
+From: Boris Burkov <boris@bur.io>
+Date: Thu, 16 Jul 2020 13:29:46 -0700
+Subject: btrfs: fix mount failure caused by race with umount
+
+From: Boris Burkov <boris@bur.io>
+
+commit 48cfa61b58a1fee0bc49eef04f8ccf31493b7cdd upstream.
+
+It is possible to cause a btrfs mount to fail by racing it with a slow
+umount. The crux of the sequence is generic_shutdown_super not yet
+calling sop->put_super before btrfs_mount_root calls btrfs_open_devices.
+If that occurs, btrfs_open_devices will decide the opened counter is
+non-zero, increment it, and skip resetting fs_devices->total_rw_bytes to
+0. From here, mount will call sget which will result in grab_super
+trying to take the super block umount semaphore. That semaphore will be
+held by the slow umount, so mount will block. Before up-ing the
+semaphore, umount will delete the super block, resulting in mount's sget
+reliably allocating a new one, which causes the mount path to dutifully
+fill it out, and increment total_rw_bytes a second time, which causes
+the mount to fail, as we see double the expected bytes.
+
+Here is the sequence laid out in greater detail:
+
+CPU0                                                    CPU1
+down_write sb->s_umount
+btrfs_kill_super
+  kill_anon_super(sb)
+    generic_shutdown_super(sb);
+      shrink_dcache_for_umount(sb);
+      sync_filesystem(sb);
+      evict_inodes(sb); // SLOW
+
+                                              btrfs_mount_root
+                                                btrfs_scan_one_device
+                                                fs_devices = device->fs_devices
+                                                fs_info->fs_devices = fs_devices
+                                                // fs_devices-opened makes this a no-op
+                                                btrfs_open_devices(fs_devices, mode, fs_type)
+                                                s = sget(fs_type, test, set, flags, fs_info);
+                                                  find sb in s_instances
+                                                  grab_super(sb);
+                                                    down_write(&s->s_umount); // blocks
+
+      sop->put_super(sb)
+        // sb->fs_devices->opened == 2; no-op
+      spin_lock(&sb_lock);
+      hlist_del_init(&sb->s_instances);
+      spin_unlock(&sb_lock);
+      up_write(&sb->s_umount);
+                                                    return 0;
+                                                  retry lookup
+                                                  don't find sb in s_instances (deleted by CPU0)
+                                                  s = alloc_super
+                                                  return s;
+                                                btrfs_fill_super(s, fs_devices, data)
+                                                  open_ctree // fs_devices total_rw_bytes improperly set!
+                                                    btrfs_read_chunk_tree
+                                                      read_one_dev // increment total_rw_bytes again!!
+                                                      super_total_bytes < fs_devices->total_rw_bytes // ERROR!!!
+
+To fix this, we clear total_rw_bytes from within btrfs_read_chunk_tree
+before the calls to read_one_dev, while holding the sb umount semaphore
+and the uuid mutex.
+
+To reproduce, it is sufficient to dirty a decent number of inodes, then
+quickly umount and mount.
+
+  for i in $(seq 0 500)
+  do
+    dd if=/dev/zero of="/mnt/foo/$i" bs=1M count=1
+  done
+  umount /mnt/foo&
+  mount /mnt/foo
+
+does the trick for me.
+
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Boris Burkov <boris@bur.io>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/volumes.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -6902,6 +6902,14 @@ int btrfs_read_chunk_tree(struct btrfs_f
+       mutex_lock(&fs_info->chunk_mutex);
+       /*
++       * It is possible for mount and umount to race in such a way that
++       * we execute this code path, but open_fs_devices failed to clear
++       * total_rw_bytes. We certainly want it cleared before reading the
++       * device items, so clear it here.
++       */
++      fs_info->fs_devices->total_rw_bytes = 0;
++
++      /*
+        * Read all device items, and then all the chunk items. All
+        * device items are found before any chunk item (their object id
+        * is smaller than the lowest possible object id for a chunk
diff --git a/queue-4.14/btrfs-fix-page-leaks-after-failure-to-lock-page-for-delalloc.patch b/queue-4.14/btrfs-fix-page-leaks-after-failure-to-lock-page-for-delalloc.patch
new file mode 100644 (file)
index 0000000..f97e2f4
--- /dev/null
@@ -0,0 +1,38 @@
+From 5909ca110b29aa16b23b52b8de8d3bb1035fd738 Mon Sep 17 00:00:00 2001
+From: Robbie Ko <robbieko@synology.com>
+Date: Mon, 20 Jul 2020 09:42:09 +0800
+Subject: btrfs: fix page leaks after failure to lock page for delalloc
+
+From: Robbie Ko <robbieko@synology.com>
+
+commit 5909ca110b29aa16b23b52b8de8d3bb1035fd738 upstream.
+
+When locking pages for delalloc, we check if it's dirty and mapping still
+matches. If it does not match, we need to return -EAGAIN and release all
+pages. Only the current page was put though, iterate over all the
+remaining pages too.
+
+CC: stable@vger.kernel.org # 4.14+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: Nikolay Borisov <nborisov@suse.com>
+Signed-off-by: Robbie Ko <robbieko@synology.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent_io.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -1721,7 +1721,8 @@ static int __process_pages_contig(struct
+                               if (!PageDirty(pages[i]) ||
+                                   pages[i]->mapping != mapping) {
+                                       unlock_page(pages[i]);
+-                                      put_page(pages[i]);
++                                      for (; i < ret; i++)
++                                              put_page(pages[i]);
+                                       err = -EAGAIN;
+                                       goto out;
+                               }
diff --git a/queue-4.14/btrfs-qgroup-fix-data-leak-caused-by-race-between-writeback-and-truncate.patch b/queue-4.14/btrfs-qgroup-fix-data-leak-caused-by-race-between-writeback-and-truncate.patch
new file mode 100644 (file)
index 0000000..7954123
--- /dev/null
@@ -0,0 +1,114 @@
+From fa91e4aa1716004ea8096d5185ec0451e206aea0 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Fri, 17 Jul 2020 15:12:05 +0800
+Subject: btrfs: qgroup: fix data leak caused by race between writeback and truncate
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit fa91e4aa1716004ea8096d5185ec0451e206aea0 upstream.
+
+[BUG]
+When running tests like generic/013 on test device with btrfs quota
+enabled, it can normally lead to data leak, detected at unmount time:
+
+  BTRFS warning (device dm-3): qgroup 0/5 has unreleased space, type 0 rsv 4096
+  ------------[ cut here ]------------
+  WARNING: CPU: 11 PID: 16386 at fs/btrfs/disk-io.c:4142 close_ctree+0x1dc/0x323 [btrfs]
+  RIP: 0010:close_ctree+0x1dc/0x323 [btrfs]
+  Call Trace:
+   btrfs_put_super+0x15/0x17 [btrfs]
+   generic_shutdown_super+0x72/0x110
+   kill_anon_super+0x18/0x30
+   btrfs_kill_super+0x17/0x30 [btrfs]
+   deactivate_locked_super+0x3b/0xa0
+   deactivate_super+0x40/0x50
+   cleanup_mnt+0x135/0x190
+   __cleanup_mnt+0x12/0x20
+   task_work_run+0x64/0xb0
+   __prepare_exit_to_usermode+0x1bc/0x1c0
+   __syscall_return_slowpath+0x47/0x230
+   do_syscall_64+0x64/0xb0
+   entry_SYSCALL_64_after_hwframe+0x44/0xa9
+  ---[ end trace caf08beafeca2392 ]---
+  BTRFS error (device dm-3): qgroup reserved space leaked
+
+[CAUSE]
+In the offending case, the offending operations are:
+2/6: writev f2X[269 1 0 0 0 0] [1006997,67,288] 0
+2/7: truncate f2X[269 1 0 0 48 1026293] 18388 0
+
+The following sequence of events could happen after the writev():
+       CPU1 (writeback)                |               CPU2 (truncate)
+-----------------------------------------------------------------
+btrfs_writepages()                     |
+|- extent_write_cache_pages()          |
+   |- Got page for 1003520             |
+   |  1003520 is Dirty, no writeback   |
+   |  So (!clear_page_dirty_for_io())   |
+   |  gets called for it               |
+   |- Now page 1003520 is Clean.       |
+   |                                   | btrfs_setattr()
+   |                                   | |- btrfs_setsize()
+   |                                   |    |- truncate_setsize()
+   |                                   |       New i_size is 18388
+   |- __extent_writepage()             |
+   |  |- page_offset() > i_size                |
+      |- btrfs_invalidatepage()                |
+        |- Page is clean, so no qgroup |
+           callback executed
+
+This means, the qgroup reserved data space is not properly released in
+btrfs_invalidatepage() as the page is Clean.
+
+[FIX]
+Instead of checking the dirty bit of a page, call
+btrfs_qgroup_free_data() unconditionally in btrfs_invalidatepage().
+
+As qgroup rsv are completely bound to the QGROUP_RESERVED bit of
+io_tree, not bound to page status, thus we won't cause double freeing
+anyway.
+
+Fixes: 0b34c261e235 ("btrfs: qgroup: Prevent qgroup->reserved from going subzero")
+CC: stable@vger.kernel.org # 4.14+
+Reviewed-by: Josef Bacik <josef@toxicpanda.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/inode.c |   23 ++++++++++-------------
+ 1 file changed, 10 insertions(+), 13 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -9197,20 +9197,17 @@ again:
+       /*
+        * Qgroup reserved space handler
+        * Page here will be either
+-       * 1) Already written to disk
+-       *    In this case, its reserved space is released from data rsv map
+-       *    and will be freed by delayed_ref handler finally.
+-       *    So even we call qgroup_free_data(), it won't decrease reserved
+-       *    space.
+-       * 2) Not written to disk
+-       *    This means the reserved space should be freed here. However,
+-       *    if a truncate invalidates the page (by clearing PageDirty)
+-       *    and the page is accounted for while allocating extent
+-       *    in btrfs_check_data_free_space() we let delayed_ref to
+-       *    free the entire extent.
++       * 1) Already written to disk or ordered extent already submitted
++       *    Then its QGROUP_RESERVED bit in io_tree is already cleaned.
++       *    Qgroup will be handled by its qgroup_record then.
++       *    btrfs_qgroup_free_data() call will do nothing here.
++       *
++       * 2) Not written to disk yet
++       *    Then btrfs_qgroup_free_data() call will clear the QGROUP_RESERVED
++       *    bit of its io_tree, and free the qgroup reserved data space.
++       *    Since the IO will never happen for this page.
+        */
+-      if (PageDirty(page))
+-              btrfs_qgroup_free_data(inode, NULL, page_start, PAGE_SIZE);
++      btrfs_qgroup_free_data(inode, NULL, page_start, PAGE_SIZE);
+       if (!inode_evicting) {
+               clear_extent_bit(tree, page_start, page_end,
+                                EXTENT_LOCKED | EXTENT_DIRTY |
index b5965284ea771625ce8e29c852234704c2189f34..ff2b0b4d7d113923f94acb7612697bb316b1cd72 100644 (file)
@@ -12,3 +12,10 @@ irqdomain-treewide-keep-firmware-node-unconditionall.patch
 sunrpc-reverting-d03727b248d0-nfsv4-fix-close-not-waiting-for-direct-io-compeletion.patch
 spi-spi-fsl-dspi-exit-the-isr-with-irq_none-when-it-s-not-ours.patch
 ib-umem-fix-reference-count-leak-in-ib_umem_odp_get.patch
+uprobes-change-handle_swbp-to-send-sigtrap-with-si_code-si_kernel-to-fix-gdb-regression.patch
+alsa-info-drop-warn_on-from-buffer-null-sanity-check.patch
+asoc-rt5670-correct-rt5670_ldo_sel_mask.patch
+btrfs-fix-double-free-on-ulist-after-backref-resolution-failure.patch
+btrfs-fix-mount-failure-caused-by-race-with-umount.patch
+btrfs-qgroup-fix-data-leak-caused-by-race-between-writeback-and-truncate.patch
+btrfs-fix-page-leaks-after-failure-to-lock-page-for-delalloc.patch
diff --git a/queue-4.14/uprobes-change-handle_swbp-to-send-sigtrap-with-si_code-si_kernel-to-fix-gdb-regression.patch b/queue-4.14/uprobes-change-handle_swbp-to-send-sigtrap-with-si_code-si_kernel-to-fix-gdb-regression.patch
new file mode 100644 (file)
index 0000000..d1ca7ef
--- /dev/null
@@ -0,0 +1,65 @@
+From fe5ed7ab99c656bd2f5b79b49df0e9ebf2cead8a Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Thu, 23 Jul 2020 17:44:20 +0200
+Subject: uprobes: Change handle_swbp() to send SIGTRAP with si_code=SI_KERNEL, to fix GDB regression
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit fe5ed7ab99c656bd2f5b79b49df0e9ebf2cead8a upstream.
+
+If a tracee is uprobed and it hits int3 inserted by debugger, handle_swbp()
+does send_sig(SIGTRAP, current, 0) which means si_code == SI_USER. This used
+to work when this code was written, but then GDB started to validate si_code
+and now it simply can't use breakpoints if the tracee has an active uprobe:
+
+       # cat test.c
+       void unused_func(void)
+       {
+       }
+       int main(void)
+       {
+               return 0;
+       }
+
+       # gcc -g test.c -o test
+       # perf probe -x ./test -a unused_func
+       # perf record -e probe_test:unused_func gdb ./test -ex run
+       GNU gdb (GDB) 10.0.50.20200714-git
+       ...
+       Program received signal SIGTRAP, Trace/breakpoint trap.
+       0x00007ffff7ddf909 in dl_main () from /lib64/ld-linux-x86-64.so.2
+       (gdb)
+
+The tracee hits the internal breakpoint inserted by GDB to monitor shared
+library events but GDB misinterprets this SIGTRAP and reports a signal.
+
+Change handle_swbp() to use force_sig(SIGTRAP), this matches do_int3_user()
+and fixes the problem.
+
+This is the minimal fix for -stable, arch/x86/kernel/uprobes.c is equally
+wrong; it should use send_sigtrap(TRAP_TRACE) instead of send_sig(SIGTRAP),
+but this doesn't confuse GDB and needs another x86-specific patch.
+
+Reported-by: Aaron Merey <amerey@redhat.com>
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20200723154420.GA32043@redhat.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/events/uprobes.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/events/uprobes.c
++++ b/kernel/events/uprobes.c
+@@ -1893,7 +1893,7 @@ static void handle_swbp(struct pt_regs *
+       if (!uprobe) {
+               if (is_swbp > 0) {
+                       /* No matching uprobe; signal SIGTRAP. */
+-                      send_sig(SIGTRAP, current, 0);
++                      force_sig(SIGTRAP, current);
+               } else {
+                       /*
+                        * Either we raced with uprobe_unregister() or we can't