From fd0831b98da02dfc53398ffb622bd9c95d93574e Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 19 Jul 2007 21:55:05 +0000 Subject: [PATCH] axeld + bonefish: Fixed off-by-one error in the b+ tree code splitting a node, which could result in a read beyond the block bounds thus causing a page fault. Was nicely reproducible when unzipping big archives. Now bug #1003 seems to be fixed for real. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21671 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp index 35ef590e77..4202cb8855 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp @@ -1189,8 +1189,12 @@ BPlusTree::_SplitNode(bplustree_node *node, off_t nodeOffset, // move the keys in the old node: the order is important here, // because we don't want to overwrite any contents - keys = keyIndex <= skip ? out : keyIndex - skip; + keys = keyIndex <= skip ? out - 1 : keyIndex - skip; keyIndex -= skip; + in = out - keyIndex - 1; + // Note: keyIndex and in will contain invalid values when the new key + // went to the other node. But in this case bytes and bytesAfter are + // 0 and subsequently we never use keyIndex and in. if (bytesBefore) memmove(inKeys, inKeys + total, bytesBefore); @@ -1201,8 +1205,8 @@ BPlusTree::_SplitNode(bplustree_node *node, off_t nodeOffset, if (bytesBefore) memmove(outKeyLengths, inKeyLengths + skip, keys * sizeof(uint16)); - in = out - keyIndex - 1; if (bytesAfter) { + // if byteAfter is > 0, keyIndex is larger than skip memmove(outKeyLengths + keyIndex + 1, inKeyLengths + skip + keyIndex, in * sizeof(uint16)); }