| From: Liu Bo <bo.li.liu@oracle.com> |
| Date: Wed, 14 Sep 2016 17:22:57 -0700 |
| Subject: Btrfs: memset to avoid stale content in btree node block |
| |
| commit 3eb548ee3a8042d95ad81be254e67a5222c24e03 upstream. |
| |
| During updating btree, we could push items between sibling |
| nodes/leaves, for leaves data sections starts reversely from |
| the end of the block while for nodes we only have key pairs |
| which are stored one by one from the start of the block. |
| |
| So we could do try to push key pairs from one node to the next |
| node right in the tree, and after that, we update the node's |
| nritems to reflect the correct end while leaving the stale |
| content in the node. One may intentionally corrupt the fs |
| image and access the stale content by bumping the nritems and |
| causes various crashes. |
| |
| This takes the in-memory @nritems as the correct one and |
| gets to memset the unused part of a btree node. |
| |
| Signed-off-by: Liu Bo <bo.li.liu@oracle.com> |
| Reviewed-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: David Sterba <dsterba@suse.com> |
| Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| fs/btrfs/extent_io.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| --- a/fs/btrfs/extent_io.c |
| +++ b/fs/btrfs/extent_io.c |
| @@ -3628,6 +3628,17 @@ static noinline_for_stack int write_one_ |
| if (btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID) |
| bio_flags = EXTENT_BIO_TREE_LOG; |
| |
| + /* set btree node beyond nritems with 0 to avoid stale content */ |
| + if (btrfs_header_level(eb) > 0) { |
| + u32 nritems; |
| + unsigned long end; |
| + |
| + nritems = btrfs_header_nritems(eb); |
| + end = btrfs_node_key_ptr_offset(nritems); |
| + |
| + memset_extent_buffer(eb, 0, end, eb->len - end); |
| + } |
| + |
| for (i = 0; i < num_pages; i++) { |
| struct page *p = eb->pages[i]; |
| |