AK: Avoid UAF for consecutive SinglyLinkedList removals
The iterator returned by SinglyLinkedList::remove() left `m_prev` default-initialized to `nullptr`. If the caller removed another element without first advancing, the previous node's next pointer was left dangling to the freed node. This caused a UAF in FinalizationRegistry's `remove_by_token()` when two consecutive records shared an unregister token.
This commit is contained in:
parent
75ae9abe7a
commit
df34c626d8
2 changed files with 24 additions and 0 deletions
|
|
@ -281,6 +281,7 @@ public:
|
|||
auto* next = node->next;
|
||||
new_iterator.m_node = next;
|
||||
new_iterator.m_next = next ? next->next : nullptr;
|
||||
new_iterator.m_prev = iterator.m_prev;
|
||||
delete node;
|
||||
return new_iterator;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,3 +204,26 @@ TEST_CASE(singly_linked_list_remove_does_not_leave_dangling_iterator)
|
|||
EXPECT(it == list.end());
|
||||
EXPECT(list.is_empty());
|
||||
}
|
||||
|
||||
TEST_CASE(singly_linked_list_remove_consecutive_mid_list_nodes)
|
||||
{
|
||||
SinglyLinkedList<int> list;
|
||||
list.append(1);
|
||||
list.append(2);
|
||||
list.append(3);
|
||||
list.append(4);
|
||||
|
||||
auto it = list.begin();
|
||||
++it;
|
||||
it = list.remove(it);
|
||||
EXPECT_EQ(*it, 3);
|
||||
it = list.remove(it);
|
||||
EXPECT_EQ(*it, 4);
|
||||
|
||||
it = list.begin();
|
||||
EXPECT_EQ(*it, 1);
|
||||
++it;
|
||||
EXPECT_EQ(*it, 4);
|
||||
++it;
|
||||
EXPECT(it == list.end());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue