Skip to contentSkip to conversation

Patch "Btrfs: fix tree search logic when replaying directory entry deletes" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Jan 3, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

Btrfs: fix tree search logic when replaying directory entry deletes

to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
btrfs-fix-tree-search-logic-when-replaying-directory-entry-deletes.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 2a7bf53f577e49c43de4ffa7776056de26db65d9 Mon Sep 17 00:00:00 2001

From: Robbie Ko <[email protected]>
Date: Fri, 7 Oct 2016 17:30:47 +0800
Subject: Btrfs: fix tree search logic when replaying directory entry deletes

From: Robbie Ko <[email protected]>

commit 2a7bf53f577e49c43de4ffa7776056de26db65d9 upstream.

If a log tree has a layout like the following:

leaf N:

        ...
        item 240 key (282 DIR_LOG_ITEM 0) itemoff 8189 itemsize 8
                dir log end 1275809046
leaf N + 1:
        item 0 key (282 DIR_LOG_ITEM 3936149215) itemoff 16275 itemsize 8
                dir log end 18446744073709551615
        ...

When we pass the value 1275809046 + 1 as the parameter start_ret to the function tree-log.c:find_dir_range() (done by replay_dir_deletes()), we end up with path->slots[0] having the value 239 (points to the last item of leaf N, item 240). Because the dir log item in that position has an offset value smaller than *start_ret (1275809046 + 1) we need to move on to the next leaf, however the logic for that is wrong since it compares the current slot to the number of items in the leaf, which is smaller and therefore we don't lookup for the next leaf but instead we set the slot to point to an item that does not exist, at slot 240, and we later operate on that slot which has unexpected content or in the worst case can result in an invalid memory access (accessing beyond the last page of leaf N's extent buffer).

So fix the logic that checks when we need to lookup at the next leaf by first incrementing the slot and only after to check if that slot is beyond the last item of the current leaf.

Fixes e02119d5a7b4 (Btrfs: Add a write ahead tree log to optimize synchronous operations)
[Modified changelog for clarity and correctness]
---
 fs/btrfs/tree-log.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
fs/btrfs/tree-log.c +1 -2
@@ -1923,12 +1923,11 @@ static noinline int find_dir_range(struc
 next:
 	/* check the next slot in the tree to see if it is a valid item */
 	nritems = btrfs_header_nritems(path->nodes[0]);
+	path->slots[0]++;
 	if (path->slots[0] >= nritems) {
 		ret = btrfs_next_leaf(root, path);
 		if (ret)
 			goto out;
-	} else {
-		path->slots[0]++;
 	}
 
 	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);

Patches currently in stable-queue which might be from [email protected] are

queue-4.4/btrfs-fix-tree-search-logic-when-replaying-directory-entry-deletes.patch