1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

InventoryManager: Disallow resizing or deleting inventory lists that are in use (#13360)

Naive solution to prevent InventoryList UAF and OOB ItemStack access caused by shrink/clear operations on InventoryLists within callbacks of an inventory action.

Co-authored-by: Desour <ds.desour@proton.me>
This commit is contained in:
SmallJoker 2023-04-22 17:42:36 +02:00 committed by GitHub
parent 4158b72971
commit 0fb6dbab36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 0 deletions

View file

@ -452,6 +452,9 @@ void InventoryList::setSize(u32 newsize)
if (newsize == m_items.size())
return;
if (newsize < m_items.size())
checkResizeLock();
m_items.resize(newsize);
m_size = newsize;
setModified();
@ -549,6 +552,8 @@ void InventoryList::deSerialize(std::istream &is)
InventoryList & InventoryList::operator = (const InventoryList &other)
{
checkResizeLock();
m_items = other.m_items;
m_size = other.m_size;
m_width = other.m_width;
@ -796,6 +801,15 @@ u32 InventoryList::moveItem(u32 i, InventoryList *dest, u32 dest_i,
return (oldcount - item1.count);
}
void InventoryList::checkResizeLock()
{
if (m_resize_locks == 0)
return; // OK
throw BaseException("InventoryList '" + m_name
+ "' is currently in use and cannot be deleted or resized.");
}
/*
Inventory
*/
@ -807,6 +821,12 @@ Inventory::~Inventory()
void Inventory::clear()
{
for (auto &m_list : m_lists) {
// Placing this check within the destructor would be a logical solution
// but that's generally a bad idea, thus manual calls beforehand:
m_list->checkResizeLock();
}
for (auto &m_list : m_lists) {
delete m_list;
}
@ -948,7 +968,9 @@ InventoryList * Inventory::addList(const std::string &name, u32 size)
// Remove existing lists
s32 i = getListIndex(name);
if (i != -1) {
m_lists[i]->checkResizeLock();
delete m_lists[i];
m_lists[i] = new InventoryList(name, size, m_itemdef);
m_lists[i]->setModified();
return m_lists[i];
@ -978,6 +1000,8 @@ bool Inventory::deleteList(const std::string &name)
if(i == -1)
return false;
m_lists[i]->checkResizeLock();
setModified();
delete m_lists[i];
m_lists.erase(m_lists.begin() + i);