]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 11 Nov 2018 20:57:05 +0000 (12:57 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 11 Nov 2018 20:57:05 +0000 (12:57 -0800)
added patches:
btrfs-fix-null-pointer-dereference-on-compressed-write-path-error.patch
btrfs-set-max_extent_size-properly.patch

queue-4.4/btrfs-fix-null-pointer-dereference-on-compressed-write-path-error.patch [new file with mode: 0644]
queue-4.4/btrfs-set-max_extent_size-properly.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/btrfs-fix-null-pointer-dereference-on-compressed-write-path-error.patch b/queue-4.4/btrfs-fix-null-pointer-dereference-on-compressed-write-path-error.patch
new file mode 100644 (file)
index 0000000..4e48f39
--- /dev/null
@@ -0,0 +1,46 @@
+From 3527a018c00e5dbada2f9d7ed5576437b6dd5cfb Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Sat, 13 Oct 2018 00:37:25 +0100
+Subject: Btrfs: fix null pointer dereference on compressed write path error
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 3527a018c00e5dbada2f9d7ed5576437b6dd5cfb upstream.
+
+At inode.c:compress_file_range(), under the "free_pages_out" label, we can
+end up dereferencing the "pages" pointer when it has a NULL value. This
+case happens when "start" has a value of 0 and we fail to allocate memory
+for the "pages" pointer. When that happens we jump to the "cont" label and
+then enter the "if (start == 0)" branch where we immediately call the
+cow_file_range_inline() function. If that function returns 0 (success
+creating an inline extent) or an error (like -ENOMEM for example) we jump
+to the "free_pages_out" label and then access "pages[i]" leading to a NULL
+pointer dereference, since "nr_pages" has a value greater than zero at
+that point.
+
+Fix this by setting "nr_pages" to 0 when we fail to allocate memory for
+the "pages" pointer.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=201119
+Fixes: 771ed689d2cd ("Btrfs: Optimize compressed writeback and reads")
+CC: stable@vger.kernel.org # 4.4+
+Reviewed-by: Liu Bo <bo.liu@linux.alibaba.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/inode.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -481,6 +481,7 @@ again:
+               pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS);
+               if (!pages) {
+                       /* just bail out to the uncompressed code */
++                      nr_pages = 0;
+                       goto cont;
+               }
diff --git a/queue-4.4/btrfs-set-max_extent_size-properly.patch b/queue-4.4/btrfs-set-max_extent_size-properly.patch
new file mode 100644 (file)
index 0000000..7fb255a
--- /dev/null
@@ -0,0 +1,97 @@
+From ad22cf6ea47fa20fbe11ac324a0a15c0a9a4a2a9 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Fri, 12 Oct 2018 15:32:33 -0400
+Subject: btrfs: set max_extent_size properly
+
+From: Josef Bacik <jbacik@fb.com>
+
+commit ad22cf6ea47fa20fbe11ac324a0a15c0a9a4a2a9 upstream.
+
+We can't use entry->bytes if our entry is a bitmap entry, we need to use
+entry->max_extent_size in that case.  Fix up all the logic to make this
+consistent.
+
+CC: stable@vger.kernel.org # 4.4+
+Signed-off-by: Josef Bacik <jbacik@fb.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/free-space-cache.c |   30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -1784,6 +1784,13 @@ static int search_bitmap(struct btrfs_fr
+       return -1;
+ }
++static inline u64 get_max_extent_size(struct btrfs_free_space *entry)
++{
++      if (entry->bitmap)
++              return entry->max_extent_size;
++      return entry->bytes;
++}
++
+ /* Cache the size of the max extent in bytes */
+ static struct btrfs_free_space *
+ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
+@@ -1805,8 +1812,8 @@ find_free_space(struct btrfs_free_space_
+       for (node = &entry->offset_index; node; node = rb_next(node)) {
+               entry = rb_entry(node, struct btrfs_free_space, offset_index);
+               if (entry->bytes < *bytes) {
+-                      if (entry->bytes > *max_extent_size)
+-                              *max_extent_size = entry->bytes;
++                      *max_extent_size = max(get_max_extent_size(entry),
++                                             *max_extent_size);
+                       continue;
+               }
+@@ -1824,8 +1831,8 @@ find_free_space(struct btrfs_free_space_
+               }
+               if (entry->bytes < *bytes + align_off) {
+-                      if (entry->bytes > *max_extent_size)
+-                              *max_extent_size = entry->bytes;
++                      *max_extent_size = max(get_max_extent_size(entry),
++                                             *max_extent_size);
+                       continue;
+               }
+@@ -1837,8 +1844,10 @@ find_free_space(struct btrfs_free_space_
+                               *offset = tmp;
+                               *bytes = size;
+                               return entry;
+-                      } else if (size > *max_extent_size) {
+-                              *max_extent_size = size;
++                      } else {
++                              *max_extent_size =
++                                      max(get_max_extent_size(entry),
++                                          *max_extent_size);
+                       }
+                       continue;
+               }
+@@ -2696,8 +2705,8 @@ static u64 btrfs_alloc_from_bitmap(struc
+       err = search_bitmap(ctl, entry, &search_start, &search_bytes, true);
+       if (err) {
+-              if (search_bytes > *max_extent_size)
+-                      *max_extent_size = search_bytes;
++              *max_extent_size = max(get_max_extent_size(entry),
++                                     *max_extent_size);
+               return 0;
+       }
+@@ -2734,8 +2743,9 @@ u64 btrfs_alloc_from_cluster(struct btrf
+       entry = rb_entry(node, struct btrfs_free_space, offset_index);
+       while (1) {
+-              if (entry->bytes < bytes && entry->bytes > *max_extent_size)
+-                      *max_extent_size = entry->bytes;
++              if (entry->bytes < bytes)
++                      *max_extent_size = max(get_max_extent_size(entry),
++                                             *max_extent_size);
+               if (entry->bytes < bytes ||
+                   (!entry->bitmap && entry->offset < min_start)) {
index bcdf8834a0fd6cbeb98f12ab4112df2e0220a39c..514d9d2cb24851ae3315786e0537e80617e108c7 100644 (file)
@@ -94,3 +94,5 @@ btrfs-reset-max_extent_size-on-clear-in-a-bitmap.patch
 btrfs-make-sure-we-create-all-new-block-groups.patch
 btrfs-fix-wrong-dentries-after-fsync-of-file-that-got-its-parent-replaced.patch
 btrfs-qgroup-dirty-all-qgroups-before-rescan.patch
+btrfs-fix-null-pointer-dereference-on-compressed-write-path-error.patch
+btrfs-set-max_extent_size-properly.patch