diff --git a/Base/usr/share/man/man2/mount.md b/Base/usr/share/man/man2/mount.md index 0dd9c99a41..bb6e5a72c4 100644 --- a/Base/usr/share/man/man2/mount.md +++ b/Base/usr/share/man/man2/mount.md @@ -39,6 +39,7 @@ The following `flags` are supported: * `MS_REMOUNT`: Remount an already mounted filesystem (see below). * `MS_WXALLOWED`: Allow W^X protection circumvention for executables on this file system. * `MS_AXALLOWED`: Allow anonymous executable mappings for executables on this file system. +* `MS_NOREGULAR`: Disallow opening any regular files from this file system. These flags can be used as a security measure to limit the possible abuses of the newly mounted file system. diff --git a/Kernel/API/POSIX/unistd.h b/Kernel/API/POSIX/unistd.h index efa35bce14..5c8bec1e2f 100644 --- a/Kernel/API/POSIX/unistd.h +++ b/Kernel/API/POSIX/unistd.h @@ -29,6 +29,7 @@ extern "C" { #define MS_REMOUNT (1 << 5) #define MS_WXALLOWED (1 << 6) #define MS_AXALLOWED (1 << 7) +#define MS_NOREGULAR (1 << 8) enum { _SC_MONOTONIC_CLOCK, diff --git a/Kernel/FileSystem/VirtualFileSystem.cpp b/Kernel/FileSystem/VirtualFileSystem.cpp index 1a120a9d1f..5960a3a83b 100644 --- a/Kernel/FileSystem/VirtualFileSystem.cpp +++ b/Kernel/FileSystem/VirtualFileSystem.cpp @@ -263,6 +263,9 @@ ErrorOr> VirtualFileSystem::open(Credenti auto& inode = custody.inode(); auto metadata = inode.metadata(); + if (metadata.is_regular_file() && (custody.mount_flags() & MS_NOREGULAR)) + return EACCES; + if ((options & O_DIRECTORY) && !metadata.is_directory()) return ENOTDIR; @@ -370,6 +373,8 @@ ErrorOr> VirtualFileSystem::create(Creden return EACCES; if (parent_custody.is_readonly()) return EROFS; + if (is_regular_file(mode) && (parent_custody.mount_flags() & MS_NOREGULAR)) + return EACCES; dbgln_if(VFS_DEBUG, "VirtualFileSystem::create: '{}' in {}", basename, parent_inode.identifier()); auto uid = owner.has_value() ? owner.value().uid : credentials.euid();