Kernel: Fix setting ext2 symbolic link target
If a link was >= 60 bytes but got shrinked to 60 bytes, reading it would rebort garbage and unlinking it would leak blocks
This commit is contained in:
parent
4af9699b22
commit
5637b8602b
|
|
@ -70,6 +70,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> cleanup_indirect_block(uint32_t block, uint32_t depth);
|
BAN::ErrorOr<void> cleanup_indirect_block(uint32_t block, uint32_t depth);
|
||||||
BAN::ErrorOr<void> cleanup_default_links();
|
BAN::ErrorOr<void> cleanup_default_links();
|
||||||
|
BAN::ErrorOr<void> cleanup_data_blocks();
|
||||||
BAN::ErrorOr<void> cleanup_from_fs();
|
BAN::ErrorOr<void> cleanup_from_fs();
|
||||||
|
|
||||||
BAN::ErrorOr<void> sync();
|
BAN::ErrorOr<void> sync();
|
||||||
|
|
|
||||||
|
|
@ -171,8 +171,10 @@ namespace Kernel
|
||||||
BAN::ErrorOr<void> Ext2Inode::set_link_target_impl(BAN::StringView target)
|
BAN::ErrorOr<void> Ext2Inode::set_link_target_impl(BAN::StringView target)
|
||||||
{
|
{
|
||||||
ASSERT(mode().iflnk());
|
ASSERT(mode().iflnk());
|
||||||
if (m_inode.size < sizeof(m_inode.block) && target.size() < sizeof(m_inode.block))
|
if (target.size() < sizeof(m_inode.block))
|
||||||
{
|
{
|
||||||
|
if (m_inode.size >= sizeof(m_inode.block))
|
||||||
|
TRY(cleanup_data_blocks());
|
||||||
memset(m_inode.block, 0, sizeof(m_inode.block));
|
memset(m_inode.block, 0, sizeof(m_inode.block));
|
||||||
memcpy(m_inode.block, target.data(), target.size());
|
memcpy(m_inode.block, target.data(), target.size());
|
||||||
m_inode.size = target.size();
|
m_inode.size = target.size();
|
||||||
|
|
@ -412,10 +414,8 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> Ext2Inode::cleanup_from_fs()
|
BAN::ErrorOr<void> Ext2Inode::cleanup_data_blocks()
|
||||||
{
|
{
|
||||||
ASSERT(m_inode.links_count == 0);
|
|
||||||
|
|
||||||
if (mode().iflnk() && (size_t)size() < sizeof(m_inode.block))
|
if (mode().iflnk() && (size_t)size() < sizeof(m_inode.block))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
@ -436,12 +436,16 @@ done:
|
||||||
// mark blocks as deleted
|
// mark blocks as deleted
|
||||||
memset(m_inode.block, 0x00, sizeof(m_inode.block));
|
memset(m_inode.block, 0x00, sizeof(m_inode.block));
|
||||||
|
|
||||||
// FIXME: this is only required since fs does not get
|
|
||||||
// deleting inode from its cache
|
|
||||||
TRY(sync());
|
TRY(sync());
|
||||||
|
|
||||||
TRY(m_fs.delete_inode(ino()));
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> Ext2Inode::cleanup_from_fs()
|
||||||
|
{
|
||||||
|
ASSERT(m_inode.links_count == 0);
|
||||||
|
TRY(cleanup_data_blocks());
|
||||||
|
TRY(m_fs.delete_inode(ino()));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue