| From 6265c924b716794df1fd72b73f4977b4d009229e Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Ernesto=20A=2E=20Fern=C3=A1ndez?= |
| <ernesto.mnd.fernandez@gmail.com> |
| Date: Tue, 30 Oct 2018 15:06:07 -0700 |
| Subject: hfs: prevent btree data loss on root split |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| [ Upstream commit d057c036672f33d43a5f7344acbb08cf3a8a0c09 ] |
| |
| This bug is triggered whenever hfs_brec_update_parent() needs to split |
| the root node. The height of the btree is not increased, which leaves |
| the new node orphaned and its records lost. It is not possible for this |
| to happen on a valid hfs filesystem because the index nodes have fixed |
| length keys. |
| |
| For reasons I ignore, the hfs module does have support for a number of |
| hfsplus features. A corrupt btree header may report variable length |
| keys and trigger this bug, so it's better to fix it. |
| |
| Link: http://lkml.kernel.org/r/9750b1415685c4adca10766895f6d5ef12babdb0.1535682463.git.ernesto.mnd.fernandez@gmail.com |
| Signed-off-by: Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com> |
| Cc: Christoph Hellwig <hch@infradead.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| fs/hfs/brec.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c |
| index 9a8772465a90..da25c49203cc 100644 |
| --- a/fs/hfs/brec.c |
| +++ b/fs/hfs/brec.c |
| @@ -425,6 +425,10 @@ skip: |
| if (new_node) { |
| __be32 cnid; |
| |
| + if (!new_node->parent) { |
| + hfs_btree_inc_height(tree); |
| + new_node->parent = tree->root; |
| + } |
| fd->bnode = hfs_bnode_find(tree, new_node->parent); |
| /* create index key and entry */ |
| hfs_bnode_read_key(new_node, fd->search_key, 14); |
| -- |
| 2.17.1 |
| |