mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:38:11 +00:00
Kernel/Ext2: Avoid overflow when updating UID and GID values
Previously, attempting to update an ext2 inode with a UID or GID larger than 65535 would overflow. We now write the high bits of UIDs and GIDs to the same place that Linux does within the `osd2` struct.
This commit is contained in:
parent
7e10f76021
commit
db929e0fcf
5 changed files with 47 additions and 7 deletions
|
@ -510,8 +510,10 @@ ErrorOr<NonnullRefPtr<Inode>> Ext2FS::create_inode(Ext2FSInode& parent_inode, St
|
||||||
ext2_inode e2inode {};
|
ext2_inode e2inode {};
|
||||||
auto now = kgettimeofday().truncated_seconds_since_epoch();
|
auto now = kgettimeofday().truncated_seconds_since_epoch();
|
||||||
e2inode.i_mode = mode;
|
e2inode.i_mode = mode;
|
||||||
e2inode.i_uid = uid.value();
|
e2inode.i_uid = static_cast<u16>(uid.value());
|
||||||
e2inode.i_gid = gid.value();
|
ext2fs_set_i_uid_high(e2inode, uid.value() >> 16);
|
||||||
|
e2inode.i_gid = static_cast<u16>(gid.value());
|
||||||
|
ext2fs_set_i_gid_high(e2inode, gid.value() >> 16);
|
||||||
e2inode.i_size = 0;
|
e2inode.i_size = 0;
|
||||||
e2inode.i_atime = now;
|
e2inode.i_atime = now;
|
||||||
e2inode.i_ctime = now;
|
e2inode.i_ctime = now;
|
||||||
|
|
|
@ -471,8 +471,8 @@ InodeMetadata Ext2FSInode::metadata() const
|
||||||
metadata.inode = identifier();
|
metadata.inode = identifier();
|
||||||
metadata.size = size();
|
metadata.size = size();
|
||||||
metadata.mode = m_raw_inode.i_mode;
|
metadata.mode = m_raw_inode.i_mode;
|
||||||
metadata.uid = m_raw_inode.i_uid;
|
metadata.uid = inode_uid(m_raw_inode);
|
||||||
metadata.gid = m_raw_inode.i_gid;
|
metadata.gid = inode_gid(m_raw_inode);
|
||||||
metadata.link_count = m_raw_inode.i_links_count;
|
metadata.link_count = m_raw_inode.i_links_count;
|
||||||
metadata.atime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_atime);
|
metadata.atime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_atime);
|
||||||
metadata.ctime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_ctime);
|
metadata.ctime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_ctime);
|
||||||
|
@ -1051,10 +1051,12 @@ ErrorOr<void> Ext2FSInode::chmod(mode_t mode)
|
||||||
ErrorOr<void> Ext2FSInode::chown(UserID uid, GroupID gid)
|
ErrorOr<void> Ext2FSInode::chown(UserID uid, GroupID gid)
|
||||||
{
|
{
|
||||||
MutexLocker locker(m_inode_lock);
|
MutexLocker locker(m_inode_lock);
|
||||||
if (m_raw_inode.i_uid == uid && m_raw_inode.i_gid == gid)
|
if (inode_uid(m_raw_inode) == uid && inode_gid(m_raw_inode) == gid)
|
||||||
return {};
|
return {};
|
||||||
m_raw_inode.i_uid = uid.value();
|
m_raw_inode.i_uid = static_cast<u16>(uid.value());
|
||||||
m_raw_inode.i_gid = gid.value();
|
ext2fs_set_i_uid_high(m_raw_inode, uid.value() >> 16);
|
||||||
|
m_raw_inode.i_gid = static_cast<u16>(gid.value());
|
||||||
|
ext2fs_set_i_gid_high(m_raw_inode, gid.value() >> 16);
|
||||||
set_metadata_dirty(true);
|
set_metadata_dirty(true);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,10 @@ if [ -f mnt/bin/timezone ]; then
|
||||||
chown 0:$phys_gid mnt/bin/timezone
|
chown 0:$phys_gid mnt/bin/timezone
|
||||||
chmod 4750 mnt/bin/timezone
|
chmod 4750 mnt/bin/timezone
|
||||||
fi
|
fi
|
||||||
|
if [ -f mnt/usr/Tests/Kernel/TestExt2FS ]; then
|
||||||
|
chown 0:0 mnt/usr/Tests/Kernel/TestExt2FS
|
||||||
|
chmod 4755 mnt/usr/Tests/Kernel/TestExt2FS
|
||||||
|
fi
|
||||||
if [ -f mnt/usr/Tests/Kernel/TestMemoryDeviceMmap ]; then
|
if [ -f mnt/usr/Tests/Kernel/TestMemoryDeviceMmap ]; then
|
||||||
chown 0:0 mnt/usr/Tests/Kernel/TestMemoryDeviceMmap
|
chown 0:0 mnt/usr/Tests/Kernel/TestMemoryDeviceMmap
|
||||||
chmod 4755 mnt/usr/Tests/Kernel/TestMemoryDeviceMmap
|
chmod 4755 mnt/usr/Tests/Kernel/TestMemoryDeviceMmap
|
||||||
|
|
|
@ -40,6 +40,7 @@ serenity_test("crash.cpp" Kernel MAIN_ALREADY_DEFINED)
|
||||||
set(LIBTEST_BASED_SOURCES
|
set(LIBTEST_BASED_SOURCES
|
||||||
TestEmptyPrivateInodeVMObject.cpp
|
TestEmptyPrivateInodeVMObject.cpp
|
||||||
TestEmptySharedInodeVMObject.cpp
|
TestEmptySharedInodeVMObject.cpp
|
||||||
|
TestExt2FS.cpp
|
||||||
TestInvalidUIDSet.cpp
|
TestInvalidUIDSet.cpp
|
||||||
TestSharedInodeVMObject.cpp
|
TestSharedInodeVMObject.cpp
|
||||||
TestPosixFallocate.cpp
|
TestPosixFallocate.cpp
|
||||||
|
|
31
Tests/Kernel/TestExt2FS.cpp
Normal file
31
Tests/Kernel/TestExt2FS.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Tim Ledbetter <timledbetter@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibTest/TestCase.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
TEST_CASE(test_uid_and_gid_high_bits_are_set)
|
||||||
|
{
|
||||||
|
static constexpr auto TEST_FILE_PATH = "/home/anon/.ext2_test";
|
||||||
|
|
||||||
|
auto uid = geteuid();
|
||||||
|
EXPECT_EQ(uid, 0u);
|
||||||
|
|
||||||
|
auto fd = open(TEST_FILE_PATH, O_CREAT);
|
||||||
|
auto cleanup_guard = ScopeGuard([&] {
|
||||||
|
close(fd);
|
||||||
|
unlink(TEST_FILE_PATH);
|
||||||
|
});
|
||||||
|
|
||||||
|
EXPECT_EQ(setuid(0), 0);
|
||||||
|
EXPECT_EQ(fchown(fd, 65536, 65536), 0);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
EXPECT_EQ(fstat(fd, &st), 0);
|
||||||
|
EXPECT_EQ(st.st_uid, 65536u);
|
||||||
|
EXPECT_EQ(st.st_gid, 65536u);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue