Commit Graph

258 Commits

Author SHA1 Message Date
Andreas Kling
16f934474f Kernel+Tests: Allow deleting someone else's file in my sticky directory
This should be allowed according to Dr. POSIX. :^)
2023-01-01 10:09:02 +01:00
Andreas Kling
47b9e8e651 Kernel: Annotate VirtualFileSystem::rmdir() errors with spec comments 2023-01-01 10:09:02 +01:00
Andreas Kling
8619f2c6f3 Kernel+Tests: Remove inaccurate FIXME in sys$rmdir()
We were already handling the rmdir("..") case by refusing to remove
directories that were not empty.

This patch removes a FIXME from January 2019 and adds a test. :^)
2023-01-01 10:09:02 +01:00
Andreas Kling
8d781d0216 Kernel+Tests: Make sys$rmdir() fail with EINVAL if basename is "."
Dr. POSIX says that we should reject attempts to rmdir() the file named
"." so this patch does exactly that. We also add a test.

This solves a FIXME from January 2019. :^)
2023-01-01 10:09:02 +01:00
Liav A
2e710de2f4 Kernel/FileSystem: Prevent symlink creation in veiled directory paths
Also, try to resolve the target path and check if it is allowed to be
accessed under the unveil rules.
2022-12-21 09:17:09 +00:00
sin-ack
2a502fe232 Kernel+LibC+LibCore+UserspaceEmulator: Implement faccessat(2)
Co-Authored-By: Daniel Bertalan <dani@danielbertalan.dev>
2022-12-11 19:55:37 -07:00
sin-ack
fa692e13f9 Kernel: Use real UID/GID when checking for file access
This aligns the rest of the system with POSIX, who says that access(2)
must check against the real UID and GID, not effective ones.
2022-12-11 19:55:37 -07:00
sin-ack
d5fbdf1866 Kernel+LibC+LibCore: Implement renameat(2)
Now with the ability to specify different bases for the old and new
paths.
2022-12-11 19:55:37 -07:00
Liav A
aa9fab9c3a Kernel/FileSystem: Convert the mount table from Vector to IntrusiveList
The fact that we used a Vector meant that even if creating a Mount
object succeeded, we were still at a risk that appending to the actual
mounts Vector could fail due to OOM condition. To guard against this,
the mount table is now an IntrusiveList, which always means that when
allocation of a Mount object succeeded, then inserting that object to
the list will succeed, which allows us to fail early in case of OOM
condition.
2022-12-09 23:29:33 -07:00
Liav A
69f41eb062 Kernel: Reject create links on paths that were not unveiled as writable
This solves one of the security issues being mentioned in issue #15996.
We simply don't allow creating hardlinks on paths that were not unveiled
as writable to prevent possible bypass on a certain path that was
unveiled as non-writable.
2022-12-03 11:00:34 -07:00
sin-ack
3b03077abb Kernel: Update the ".." inode for directories after a rename
Because the ".." entry in a directory is a separate inode, if a
directory is renamed to a new location, then we should update this entry
the point to the new parent directory as well.

Co-authored-by: Liav A <liavalb@gmail.com>
2022-11-25 17:33:05 +01:00
Andreas Kling
10fa72d451 Kernel: Use AK::Time for InodeMetadata timestamps instead of time_t
Before this change, we were truncating the nanosecond part of file
timestamps in many different places.
2022-11-24 16:56:27 +01:00
Liav A
03ae9f94cf Kernel/FileSystem: Remove hardcoded unveil path of /usr/lib/Loader.so
If a program needs to execute a dynamic executable program, then it
should unveil /usr/lib/Loader.so by itself and not rely on the Kernel to
allow using this binary without any sense of respect to unveil promises
being made by the running parent program.
2022-10-24 19:41:32 -06:00
Liav A
fea3cb5ff9 Kernel/FileSystem: Discard safely filesystems when unmounted last time
This commit reached that goal of "safely discarding" a filesystem by
doing the following:
1. Stop using the s_file_system_map HashMap as it was an unsafe measure
to access pointers of FileSystems. Instead, make sure to register all
FileSystems at the VFS layer, with an IntrusiveList, to avoid problems
related to OOM conditions.
2. Make sure to cleanly remove the DiskCache object from a BlockBased
filesystem, so the destructor of such object will not need to do that in
the destruction point.
3. For ext2 filesystems, don't cache the root inode at m_inode_cache
HashMap. The reason for this is that when unmounting an ext2 filesystem,
we lookup at the cache to see if there's a reference to a cached inode
and if that's the case, we fail with EBUSY. If we keep the m_root_inode
also being referenced at the m_inode_cache map, we have 2 references to
that object, which will lead to fail with EBUSY. Also, it's much simpler
to always ask for a root inode and get it immediately from m_root_inode,
instead of looking up the cache for that inode.
2022-10-22 16:57:52 -04:00
Liav A
24977996a6 Kernel: Append root filesystem to the VFS FileBackedFileSystem list 2022-10-22 16:57:52 -04:00
Liav A
0fd7b688af Kernel: Introduce support for using FileSystem object in multiple mounts
The idea is to enable mounting FileSystem objects across multiple mounts
in contrast to what happened until now - each mount has its own unique
FileSystem object being attached to it.

Considering a situation of mounting a block device at 2 different mount
points at in system, there were a couple of critical flaws due to how
the previous "design" worked:
1. BlockBasedFileSystem(s) that pointed to the same actual device had a
separate DiskCache object being attached to them. Because both instances
were not synchronized by any means, corruption of the filesystem is most
likely achieveable by a simple cache flush of either of the instances.
2. For superblock-oriented filesystems (such as the ext2 filesystem),
lack of synchronization between both instances can lead to severe
corruption in the superblock, which could render the entire filesystem
unusable.
3. Flags of a specific filesystem implementation (for example, with xfs
on Linux, one can instruct to mount it with the discard option) must be
honored across multiple mounts, to ensure expected behavior against a
particular filesystem.

This patch put the foundations to start fix the issues mentioned above.
However, there are still major issues to solve, so this is only a start.
2022-10-22 16:57:52 -04:00
Liav A
07387ec19a Kernel+Base: Introduce MS_NOREGULAR mount flag
This flag doesn't conform to any POSIX standard nor is found in any OS
out there. The idea behind this mount flag is to ensure that only
non-regular files will be placed in a filesystem, which includes device
nodes, symbolic links, directories, FIFOs and sockets. Currently, the
only valid case for using this mount flag is for TmpFS instances, where
we want to mount a TmpFS but disallow any kind of regular file and only
allow other types of files on the filesystem.
2022-10-22 19:18:15 +02:00
Liav A
c88cc8557f Kernel/FileSystem: Make Inode::{write,read}_bytes methods non-virtual
We make these methods non-virtual because we want to ensure we properly
enforce locking of the m_inode_lock mutex. Also, for write operations,
we want to call prepare_to_write_data before the actual write. The
previous design required us to ensure the callers do that at various
places which lead to hard-to-find bugs. By moving everything to a place
where we call prepare_to_write_data only once, we eliminate a possibilty
of forgeting to call it on some code path in the kernel.
2022-09-16 14:55:45 +03:00
Andreas Kling
2cc947ede4 Kernel: Use correct timestamp in sys$utimens()
We were mixing up the nanosecond and second parts of the timestamps.

Regressed in 280694bb46.
2022-09-13 17:03:31 +02:00
Andreas Kling
280694bb46 Kernel: Update atime/ctime/mtime timestamps atomically
Instead of having three separate APIs (one for each timestamp),
there's now only Inode::update_timestamps() and it takes 3x optional
timestamps. The non-empty timestamps are updated while holding the inode
mutex, and the outside world no longer has to look at intermediate
timestamp states.
2022-08-22 17:56:03 +02:00
Andreas Kling
dbe182f1c6 Kernel: Make Inode::resolve_as_link() take credentials as input 2022-08-21 16:17:13 +02:00
Andreas Kling
c3351d4b9f Kernel: Make VirtualFileSystem functions take credentials as input
Instead of getting credentials from Process::current(), we now require
that they be provided as input to the various VFS functions.

This ensures that an atomic set of credentials is used throughout an
entire VFS operation.
2022-08-21 16:02:24 +02:00
James Bellamy
386642ffcf Kernel: Use credentials object in VirtualFileSystem
Use credentials object in mknod, create, mkdir, and symlink
2022-08-21 14:55:01 +02:00
Andreas Kling
728c3fbd14 Kernel: Use RefPtr instead of LockRefPtr for Custody
By protecting all the RefPtr<Custody> objects that may be accessed from
multiple threads at the same time (with spinlocks), we remove the need
for using LockRefPtr<Custody> (which is basically a RefPtr with a
built-in spinlock.)
2022-08-21 12:25:14 +02:00
Andreas Kling
11eee67b85 Kernel: Make self-contained locking smart pointers their own classes
Until now, our kernel has reimplemented a number of AK classes to
provide automatic internal locking:

- RefPtr
- NonnullRefPtr
- WeakPtr
- Weakable

This patch renames the Kernel classes so that they can coexist with
the original AK classes:

- RefPtr => LockRefPtr
- NonnullRefPtr => NonnullLockRefPtr
- WeakPtr => LockWeakPtr
- Weakable => LockWeakable

The goal here is to eventually get rid of the Lock* classes in favor of
using external locking.
2022-08-20 17:20:43 +02:00
Kristiyan Stoimenov
9e1bea50ee Kernel/VFS: Check that mount-point is not in use
Before committing the mount, verify that this host i-node is not already
a mount-point.
2022-08-12 19:57:18 -07:00
Liav A
fcc0e4d538 Kernel/FileSystem: Funnel calls to Inode::prepare_to_write_data method
Instead of requiring each FileSystem implementation to call this method
when trying to write data, do the calls at 2 points to avoid further
calls (or lack of them due to not remembering to use it) at other files
and locations in the codebase.
2022-07-30 23:31:08 +02:00
sin-ack
3f3f45580a Everywhere: Add sv suffix to strings relying on StringView(char const*)
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).

No functional changes.
2022-07-12 23:11:35 +02:00
Ariel Don
9a6bd85924 Kernel+LibC+VFS: Implement utimensat(3)
Create POSIX utimensat() library call and corresponding system call to
update file access and modification times.
2022-05-21 18:15:00 +02:00
Andrew Kaster
f08e91f67e Kernel: Don't check pledges or veil against code coverage data files
Coverage tools like LLVM's source-based coverage or GNU's --coverage
need to be able to write out coverage files from any binary, regardless
of its security posture. Not ignoring these pledges and veils means we
can't get our coverage data out without playing some serious tricks.

However this is pretty terrible for normal exeuction, so only skip these
checks when we explicitly configured userspace for coverage.
2022-05-02 01:46:18 +02:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Lenny Maiorani
190cf1507b Kernel: Use default constructors/destructors
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules

"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
2022-03-17 00:51:36 -07:00
Andreas Kling
580d89f093 Kernel: Put Process unveil state in a SpinlockProtected container
This makes path resolution safe to perform without holding the big lock.
2022-03-08 00:19:49 +01:00
Idan Horowitz
feb00b7105 Everywhere: Make JSON serialization fallible
This allows us to eliminate a major source of infallible allocation in
the Kernel, as well as lay down the groundwork for OOM fallibility in
userland.
2022-02-27 20:37:57 +01:00
Max Wipfli
b0df096298 Kernel/VFS: Add FIXMEs about error codes leaking data from veiled paths
Error codes can leak information about veiled paths, if the path
resolution fails with e.g. EACCESS.

This is non-trivial to fix, as there is a group of error codes we want
to propagate to the caller, such as ENOMEM.
2022-02-13 21:58:26 +02:00
Max Wipfli
e8f491b01d Kernel/VFS: Validate paths against process veil in mkdir()
VirtualFileSystem::mkdir() relies on resolve_path() returning an error,
since it is only interested in the out_parent passed as a pointer. Since
resolve_path_without_veil returns an error, no process veil validation
is done by resolve_path() in that case. Due to this problem, mkdir()
should use resolve_path_without_veil() and then manually validate if the
parent directory of the to-be-created directory is unveiled with 'c'
permissions.

This fixes a bug where the mkdir syscall would not respect the process
veil at all.
2022-02-13 21:58:26 +02:00
Max Wipfli
8c7010f282 Kernel/VFS: Clear out_parent if path is veiled
Previously, VirtualFileSystem::resolve_path() could return a non-null
RefPtr<Custody>* out_parent even if the function errored because the
path has been veiled.

If code relies on recieving the parent custody even if the path is
veiled, it should just call resolve_path_without_veil and do the veil
validation manually. This is because it could be that the parent is
unveiled but the child isn't or the other way round.
2022-02-13 21:58:26 +02:00
Andreas Kling
210689281f Kernel: Protect mounted filesystem list with spinlock instead of mutex 2022-02-03 16:11:26 +01:00
Idan Horowitz
67ce9e28a5 AK: Standardize the behaviour of GenericLexer::consume_until overloads
Before this commit all consume_until overloads aside from the Predicate
one would consume (and ignore) the stop char/string, while the
Predicate overload would not, in order to keep behaviour consistent,
the other overloads no longer consume the stop char/string as well.
2022-01-25 13:41:09 +03:30
Daniel Bertalan
182016d7c0 Kernel+LibC+LibCore+UE: Implement fchmodat(2)
This function is an extended version of `chmod(2)` that lets one control
whether to dereference symlinks, and specify a file descriptor to a
directory that will be used as the base for relative paths.
2022-01-12 14:54:12 +01:00
circl
63760603f3 Kernel+LibC+LibCore: Add lchown and fchownat functions
This modifies sys$chown to allow specifying whether or not to follow
symlinks and in which directory.

This was then used to implement lchown and fchownat in LibC and LibCore.
2022-01-01 15:08:49 +01:00
Daniel Bertalan
726c023f9e Kernel: Propagate allocation failure in resolve_path_without_veil 2021-12-30 14:16:03 +01:00
Martin Bříza
f75bab2a25 Kernel: Move symlink recursion limit to .h, increase it to 8
As pointed out by BertalanD on Discord, POSIX specifies that
_SC_SYMLOOP_MAX (implemented in the following commit) always needs to be
equal or more than _POSIX_SYMLOOP_MAX (8, defined in
LibC/bits/posix1_lim.h), hence I've increased it to that value to
comply with the standard.

The move to header is required for the following commit - to make this
constant accessible outside of the VFS class, namely in sysconf.
2021-12-21 12:54:11 -08:00
sin-ack
69ef211925 Kernel+LibC: Move errno definitions to Kernel/API/POSIX
This fixes at least half of our LibC includes in the kernel. The source
of truth for errno codes and their description strings now lives in
Kernel/API/POSIX/errno.h as an enumeration, which LibC includes.
2021-12-16 22:21:35 +03:30
Andreas Kling
0f9ca51c76 Kernel: Remove unused Inode::preopen_fd() 2021-12-06 19:22:16 +01:00
Sam Atkins
c6a97ea843 Kernel: Mark kernel smart-pointer classes as [[nodiscard]]
And cast the unused return values to void.
2021-12-05 15:31:03 +01:00
Andreas Kling
5ce753b74d Kernel: Make Inode::traverse_as_directory() callback return ErrorOr
This allows us to propagate errors from inside the callback with TRY().
2021-11-10 21:58:58 +01:00
Andreas Kling
79fa9765ca Kernel: Replace KResult and KResultOr<T> with Error and ErrorOr<T>
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace!
This was a slightly tedious refactoring that took a long time, so it's
not unlikely that some bugs crept in.

Nevertheless, it does pass basic functionality testing, and it's just
real nice to finally see the same pattern in all contexts. :^)
2021-11-08 01:10:53 +01:00
Ben Wiederhake
c05c5a7ff4 Kernel: Clarify ambiguous {File,Description}::absolute_path
Found due to smelly code in InodeFile::absolute_path.

In particular, this replaces the following misleading methods:

File::absolute_path
This method *never* returns an actual path, and if called on an
InodeFile (which is impossible), it would VERIFY_NOT_REACHED().

OpenFileDescription::try_serialize_absolute_path
OpenFileDescription::absolute_path
These methods do not guarantee to return an actual path (just like the
other method), and just like Custody::absolute_path they do not
guarantee accuracy. In particular, just renaming the method made a
TOCTOU bug obvious.

The new method signatures use KResultOr, just like
try_serialize_absolute_path() already did.
2021-10-31 12:06:28 +01:00
Ben Wiederhake
88ca12f037 Kernel: Enable early-returns from VFS::for_each_mount 2021-10-31 12:06:28 +01:00