Fix crash when mounting btrfs volumes

Found item has data offset higher than block size. Move the stream to get the
data. If the data does not fit in the block, fetch it directly from the device.

Signed-off-by: Adrien Destugues <[email protected]>

Fixes #12788.
This commit is contained in:
Hy Che
2017-03-13 19:43:44 +01:00
committed by Adrien Destugues
parent 4135f1fd20
commit 3f73d5625c
@@ -168,10 +168,22 @@ BPlusTree::_Find(struct btrfs_key &key, void** _value, size_t* _size,
stream->entries[i].Offset(), stream->entries[i].Size());
if (_value != NULL) {
*_value = malloc(stream->entries[i].Size());
memcpy(*_value, ((uint8 *)&stream->entries[0]
+ stream->entries[i].Offset()),
stream->entries[i].Size());
uint32 totalOffset = stream->entries[i].Offset() + sizeof(btrfs_header);
key.SetOffset(stream->entries[i].key.Offset());
if ((fVolume->BlockSize() - totalOffset % fVolume->BlockSize())
>= stream->entries[i].Size()) {
//If there is enough space for *_value
stream = (btrfs_stream*)cached.SetTo(physical
+ totalOffset / fVolume->BlockSize());
memcpy(*_value, ((uint8 *)&stream->header
+ totalOffset % fVolume->BlockSize()),
stream->entries[i].Size());
} else {
read_pos(fVolume->Device(), physical
* fVolume->BlockSize() + totalOffset,
*_value, stream->entries[i].Size());
}
if (_size != NULL)
*_size = stream->entries[i].Size();
}