diff --git a/Kernel/FileSystem/Ext2FS/FileSystem.cpp b/Kernel/FileSystem/Ext2FS/FileSystem.cpp index f4f354fed3..7dc9ff3ac7 100644 --- a/Kernel/FileSystem/Ext2FS/FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FS/FileSystem.cpp @@ -510,8 +510,10 @@ ErrorOr> Ext2FS::create_inode(Ext2FSInode& parent_inode, St ext2_inode e2inode {}; auto now = kgettimeofday().truncated_seconds_since_epoch(); e2inode.i_mode = mode; - e2inode.i_uid = uid.value(); - e2inode.i_gid = gid.value(); + e2inode.i_uid = static_cast(uid.value()); + ext2fs_set_i_uid_high(e2inode, uid.value() >> 16); + e2inode.i_gid = static_cast(gid.value()); + ext2fs_set_i_gid_high(e2inode, gid.value() >> 16); e2inode.i_size = 0; e2inode.i_atime = now; e2inode.i_ctime = now; diff --git a/Kernel/FileSystem/Ext2FS/Inode.cpp b/Kernel/FileSystem/Ext2FS/Inode.cpp index 9e5cdba76d..f0c600c5a3 100644 --- a/Kernel/FileSystem/Ext2FS/Inode.cpp +++ b/Kernel/FileSystem/Ext2FS/Inode.cpp @@ -471,8 +471,8 @@ InodeMetadata Ext2FSInode::metadata() const metadata.inode = identifier(); metadata.size = size(); metadata.mode = m_raw_inode.i_mode; - metadata.uid = m_raw_inode.i_uid; - metadata.gid = m_raw_inode.i_gid; + metadata.uid = inode_uid(m_raw_inode); + metadata.gid = inode_gid(m_raw_inode); metadata.link_count = m_raw_inode.i_links_count; metadata.atime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_atime); metadata.ctime = UnixDateTime::from_seconds_since_epoch(m_raw_inode.i_ctime); @@ -1051,10 +1051,12 @@ ErrorOr Ext2FSInode::chmod(mode_t mode) ErrorOr Ext2FSInode::chown(UserID uid, GroupID gid) { 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 {}; - m_raw_inode.i_uid = uid.value(); - m_raw_inode.i_gid = gid.value(); + m_raw_inode.i_uid = static_cast(uid.value()); + ext2fs_set_i_uid_high(m_raw_inode, uid.value() >> 16); + m_raw_inode.i_gid = static_cast(gid.value()); + ext2fs_set_i_gid_high(m_raw_inode, gid.value() >> 16); set_metadata_dirty(true); return {}; } diff --git a/Meta/build-root-filesystem.sh b/Meta/build-root-filesystem.sh index 8eba6b81bd..aed239f9d7 100755 --- a/Meta/build-root-filesystem.sh +++ b/Meta/build-root-filesystem.sh @@ -98,6 +98,10 @@ if [ -f mnt/bin/timezone ]; then chown 0:$phys_gid mnt/bin/timezone chmod 4750 mnt/bin/timezone 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 chown 0:0 mnt/usr/Tests/Kernel/TestMemoryDeviceMmap chmod 4755 mnt/usr/Tests/Kernel/TestMemoryDeviceMmap diff --git a/Tests/Kernel/CMakeLists.txt b/Tests/Kernel/CMakeLists.txt index eaf085e1b4..b8b3d5040b 100644 --- a/Tests/Kernel/CMakeLists.txt +++ b/Tests/Kernel/CMakeLists.txt @@ -40,6 +40,7 @@ serenity_test("crash.cpp" Kernel MAIN_ALREADY_DEFINED) set(LIBTEST_BASED_SOURCES TestEmptyPrivateInodeVMObject.cpp TestEmptySharedInodeVMObject.cpp + TestExt2FS.cpp TestInvalidUIDSet.cpp TestSharedInodeVMObject.cpp TestPosixFallocate.cpp diff --git a/Tests/Kernel/TestExt2FS.cpp b/Tests/Kernel/TestExt2FS.cpp new file mode 100644 index 0000000000..06b6ee0638 --- /dev/null +++ b/Tests/Kernel/TestExt2FS.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023, Tim Ledbetter + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +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); +}