summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorJelle Raaijmakers <jelle@gmta.nl>2022-11-26 01:17:43 +0100
committerAndreas Kling <kling@serenityos.org>2022-11-26 09:15:34 +0100
commit70a7bca92014b1698c3bfc80e7d61725b9b3222f (patch)
tree1e65b1df0a44224130c25b21ab283d9675f00a9c /Userland
parente5e00a682ba321375b465f1f49c1021e8cd700cd (diff)
downloadserenity-70a7bca92014b1698c3bfc80e7d61725b9b3222f.zip
LibSQL: Fix BTree corruption in `TreeNode::split`
After splitting a node, the new node was written to the same pointer as the current node - probably a copy / paste error. This new code requires a `.pointer() -> u32` to exist on the object to be serialized, preventing this issue from happening again. Fixes #15844.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibSQL/BTree.cpp2
-rw-r--r--Userland/Libraries/LibSQL/BTreeIterator.cpp2
-rw-r--r--Userland/Libraries/LibSQL/Database.cpp2
-rw-r--r--Userland/Libraries/LibSQL/HashIndex.cpp12
-rw-r--r--Userland/Libraries/LibSQL/Serializer.h4
-rw-r--r--Userland/Libraries/LibSQL/TreeNode.cpp10
6 files changed, 16 insertions, 16 deletions
diff --git a/Userland/Libraries/LibSQL/BTree.cpp b/Userland/Libraries/LibSQL/BTree.cpp
index d83a353e8d..179af103b3 100644
--- a/Userland/Libraries/LibSQL/BTree.cpp
+++ b/Userland/Libraries/LibSQL/BTree.cpp
@@ -56,7 +56,7 @@ TreeNode* BTree::new_root()
{
set_pointer(new_record_pointer());
m_root = make<TreeNode>(*this, nullptr, m_root.leak_ptr(), pointer());
- serializer().serialize_and_write(*m_root.ptr(), m_root->pointer());
+ serializer().serialize_and_write(*m_root.ptr());
if (on_new_root)
on_new_root();
return m_root;
diff --git a/Userland/Libraries/LibSQL/BTreeIterator.cpp b/Userland/Libraries/LibSQL/BTreeIterator.cpp
index d062287489..f761c39bee 100644
--- a/Userland/Libraries/LibSQL/BTreeIterator.cpp
+++ b/Userland/Libraries/LibSQL/BTreeIterator.cpp
@@ -232,7 +232,7 @@ bool BTreeIterator::update(Key const& new_value)
// We are friend of BTree and TreeNode. Don't know how I feel about that.
m_current->m_entries[m_index] = new_value;
- m_current->tree().serializer().serialize_and_write(*m_current, m_current->pointer());
+ m_current->tree().serializer().serialize_and_write(*m_current);
return true;
}
diff --git a/Userland/Libraries/LibSQL/Database.cpp b/Userland/Libraries/LibSQL/Database.cpp
index 3f25267632..55a8af7dac 100644
--- a/Userland/Libraries/LibSQL/Database.cpp
+++ b/Userland/Libraries/LibSQL/Database.cpp
@@ -223,7 +223,7 @@ ErrorOr<void> Database::update(Row& tuple)
VERIFY(m_table_cache.get(tuple.table()->key().hash()).has_value());
// TODO Check constraints
m_serializer.reset();
- m_serializer.serialize_and_write<Tuple>(tuple, tuple.pointer());
+ m_serializer.serialize_and_write<Tuple>(tuple);
// TODO update indexes defined on table.
return {};
diff --git a/Userland/Libraries/LibSQL/HashIndex.cpp b/Userland/Libraries/LibSQL/HashIndex.cpp
index 2642ada69a..bde86fbb7d 100644
--- a/Userland/Libraries/LibSQL/HashIndex.cpp
+++ b/Userland/Libraries/LibSQL/HashIndex.cpp
@@ -140,7 +140,7 @@ bool HashBucket::insert(Key const& key)
return false;
}
m_entries.append(key);
- m_hash_index.serializer().serialize_and_write(*this, pointer());
+ m_hash_index.serializer().serialize_and_write(*this);
return true;
}
@@ -226,10 +226,10 @@ HashIndex::HashIndex(Serializer& serializer, NonnullRefPtr<TupleDescriptor> cons
} else {
auto bucket = append_bucket(0u, 1u, new_record_pointer());
bucket->m_inflated = true;
- serializer.serialize_and_write(*bucket, bucket->pointer());
+ serializer.serialize_and_write(*bucket);
bucket = append_bucket(1u, 1u, new_record_pointer());
bucket->m_inflated = true;
- serializer.serialize_and_write(*bucket, bucket->pointer());
+ serializer.serialize_and_write(*bucket);
m_nodes.append(first_node);
write_directory_to_write_ahead_log();
}
@@ -283,7 +283,7 @@ HashBucket* HashIndex::get_bucket_for_insert(Key const& key)
}
if (moved > 0) {
dbgln_if(SQL_DEBUG, "Moved {} entries from bucket #{} to #{}", moved, base_index, ix);
- serializer().serialize_and_write(*sub_bucket, sub_bucket->pointer());
+ serializer().serialize_and_write(*sub_bucket);
}
total_moved += moved;
}
@@ -292,7 +292,7 @@ HashBucket* HashIndex::get_bucket_for_insert(Key const& key)
else
dbgln_if(SQL_DEBUG, "Nothing redistributed from bucket #{}", base_index);
bucket->set_local_depth(bucket->local_depth() + 1);
- serializer().serialize_and_write(*bucket, bucket->pointer());
+ serializer().serialize_and_write(*bucket);
write_directory_to_write_ahead_log();
auto bucket_after_redistribution = get_bucket(key_hash % size());
@@ -327,7 +327,7 @@ void HashIndex::write_directory_to_write_ahead_log()
size_t num_node = 0u;
while (offset < size()) {
HashDirectoryNode node(*this, num_node, offset);
- serializer().serialize_and_write(node, node.pointer());
+ serializer().serialize_and_write(node);
offset += node.number_of_pointers();
}
}
diff --git a/Userland/Libraries/LibSQL/Serializer.h b/Userland/Libraries/LibSQL/Serializer.h
index 914a99fa0f..0cb089be67 100644
--- a/Userland/Libraries/LibSQL/Serializer.h
+++ b/Userland/Libraries/LibSQL/Serializer.h
@@ -108,12 +108,12 @@ public:
void serialize(String const&);
template<typename T>
- bool serialize_and_write(T const& t, u32 pointer)
+ bool serialize_and_write(T const& t)
{
VERIFY(m_heap.ptr() != nullptr);
reset();
serialize<T>(t);
- m_heap->add_to_wal(pointer, m_buffer);
+ m_heap->add_to_wal(t.pointer(), m_buffer);
return true;
}
diff --git a/Userland/Libraries/LibSQL/TreeNode.cpp b/Userland/Libraries/LibSQL/TreeNode.cpp
index 749570e2cb..17759d0df5 100644
--- a/Userland/Libraries/LibSQL/TreeNode.cpp
+++ b/Userland/Libraries/LibSQL/TreeNode.cpp
@@ -172,7 +172,7 @@ bool TreeNode::update_key_pointer(Key const& key)
if (m_entries[ix].pointer() != key.pointer()) {
m_entries[ix].set_pointer(key.pointer());
dump_if(SQL_DEBUG, "To WAL");
- tree().serializer().serialize_and_write<TreeNode>(*this, pointer());
+ tree().serializer().serialize_and_write<TreeNode>(*this);
}
return true;
}
@@ -277,7 +277,7 @@ void TreeNode::just_insert(Key const& key, TreeNode* right)
split();
} else {
dump_if(SQL_DEBUG, "To WAL");
- tree().serializer().serialize_and_write(*this, pointer());
+ tree().serializer().serialize_and_write(*this);
}
return;
}
@@ -289,7 +289,7 @@ void TreeNode::just_insert(Key const& key, TreeNode* right)
split();
} else {
dump_if(SQL_DEBUG, "To WAL");
- tree().serializer().serialize_and_write(*this, pointer());
+ tree().serializer().serialize_and_write(*this);
}
}
@@ -327,9 +327,9 @@ void TreeNode::split()
auto median = m_entries.take_last();
dump_if(SQL_DEBUG, "Split Left To WAL");
- tree().serializer().serialize_and_write(*this, pointer());
+ tree().serializer().serialize_and_write(*this);
new_node->dump_if(SQL_DEBUG, "Split Right to WAL");
- tree().serializer().serialize_and_write(*new_node, pointer());
+ tree().serializer().serialize_and_write(*new_node);
m_up->just_insert(median, new_node);
}