From: Greg Kroah-Hartman Date: Sun, 26 Jul 2020 12:41:01 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.14.190~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=77386e35bb912ce3ea08c98bbf6b980084ee60e5;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches 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 --- 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 index 00000000000..0660c311bf9 --- /dev/null +++ b/queue-4.14/alsa-info-drop-warn_on-from-buffer-null-sanity-check.patch @@ -0,0 +1,43 @@ +From 60379ba08532eca861e933b389526a4dc89e0c42 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 17 Jul 2020 10:40:23 +0200 +Subject: ALSA: info: Drop WARN_ON() from buffer NULL sanity check + +From: Takashi Iwai + +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: +Link: https://lore.kernel.org/r/20200717084023.5928-1-tiwai@suse.de +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..9d998d504b7 --- /dev/null +++ b/queue-4.14/asoc-rt5670-correct-rt5670_ldo_sel_mask.patch @@ -0,0 +1,42 @@ +From 5cacc6f5764e94fa753b2c1f5f7f1f3f74286e82 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sun, 28 Jun 2020 17:52:27 +0200 +Subject: ASoC: rt5670: Correct RT5670_LDO_SEL_MASK + +From: Hans de Goede + +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 +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200628155231.71089-3-hdegoede@redhat.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e5bbabd9ebd --- /dev/null +++ b/queue-4.14/btrfs-fix-double-free-on-ulist-after-backref-resolution-failure.patch @@ -0,0 +1,159 @@ +From 580c079b5766ac706f56eec5c79aee4bf929fef6 Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Mon, 13 Jul 2020 15:11:56 +0100 +Subject: btrfs: fix double free on ulist after backref resolution failure + +From: Filipe Manana + +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): [] copy_process+0x755/0x1eb0 + softirqs last enabled at (0): [] 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 +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..80ca821288e --- /dev/null +++ b/queue-4.14/btrfs-fix-mount-failure-caused-by-race-with-umount.patch @@ -0,0 +1,104 @@ +From 48cfa61b58a1fee0bc49eef04f8ccf31493b7cdd Mon Sep 17 00:00:00 2001 +From: Boris Burkov +Date: Thu, 16 Jul 2020 13:29:46 -0700 +Subject: btrfs: fix mount failure caused by race with umount + +From: Boris Burkov + +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 +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f97e2f4590e --- /dev/null +++ b/queue-4.14/btrfs-fix-page-leaks-after-failure-to-lock-page-for-delalloc.patch @@ -0,0 +1,38 @@ +From 5909ca110b29aa16b23b52b8de8d3bb1035fd738 Mon Sep 17 00:00:00 2001 +From: Robbie Ko +Date: Mon, 20 Jul 2020 09:42:09 +0800 +Subject: btrfs: fix page leaks after failure to lock page for delalloc + +From: Robbie Ko + +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 +Reviewed-by: Nikolay Borisov +Signed-off-by: Robbie Ko +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..795412314cd --- /dev/null +++ b/queue-4.14/btrfs-qgroup-fix-data-leak-caused-by-race-between-writeback-and-truncate.patch @@ -0,0 +1,114 @@ +From fa91e4aa1716004ea8096d5185ec0451e206aea0 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +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 + +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 +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 | diff --git a/queue-4.14/series b/queue-4.14/series index b5965284ea7..ff2b0b4d7d1 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -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 index 00000000000..d1ca7ef0186 --- /dev/null +++ b/queue-4.14/uprobes-change-handle_swbp-to-send-sigtrap-with-si_code-si_kernel-to-fix-gdb-regression.patch @@ -0,0 +1,65 @@ +From fe5ed7ab99c656bd2f5b79b49df0e9ebf2cead8a Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +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 + +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 +Signed-off-by: Oleg Nesterov +Signed-off-by: Ingo Molnar +Reviewed-by: Srikar Dronamraju +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20200723154420.GA32043@redhat.com +Signed-off-by: Greg Kroah-Hartman + +--- + 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