Commit Graph

34 Commits

Author SHA1 Message Date
Brian Gianforcaro
4df1657898 Tests: Add coverage for sys$alarm() success case 2021-08-03 18:44:01 +02:00
Brian Gianforcaro
ea401fb3c3 Tests: Add coverage for sys$alarm() canceling a stale timer
This is a regression test to validate the functionality that was
reported broken in #9071, where the kernel would spin attempting
to cancel a stale timer.
2021-08-03 18:44:01 +02:00
Andreas Kling
bccdc08487 Kernel: Unmapping a non-mapped region with munmap() should be a no-op
Not a regression per se from 0fcb9efd86
since we were crashing before that which is obviously worse.
2021-07-30 13:16:55 +02:00
Brian Gianforcaro
c9395d7e9a Tests: Validate unmapping 0x0 doesn't crash the Kernel
Previously unmapping any offset starting at 0x0 would assert in the
kernel, add a regression test to validate the fix.

Co-authored-by: Federico Guerinoni <guerinoni.federico@gmail.com>
2021-07-30 11:28:55 +02:00
Brian Gianforcaro
c2282ee28d Tests: Add test coverage for sys$pledge(..) argument validation 2021-07-23 19:02:25 +02:00
Brian Gianforcaro
fa448456a9 Tests: Add test coverage for sys$unveil(..) argument validation 2021-07-23 19:02:25 +02:00
Peter Bindels
ef85c4f747 Tests: Make mmap test point to new kernel address too
During a recent commit the 64-bit kernel was moved to a different
address, breaking this test (unnoticed). This fixes it, so we can
turn on breaking x86_64 tests on the CI again.
2021-07-18 22:08:20 +02:00
Daniel Bertalan
6821cd45ed Tests: Fix compile errors on Clang
Since Clang enables a couple of warnings that we don't have in GCC,
these were not caught before. Included fixes:

- Use correct printf format string for `size_t`
- Don't compare Nonnull(Ref|Own)Ptr` to nullptr
- Fix unsigned int& => unsigned long& conversion
2021-07-14 13:12:25 +02:00
Andrew Kaster
4cc75501d7 Utilities+Tests: Convert test_efault to be LibTest based
This test exposed a kernel panic in is_user_range calculations, so let's
convert it to be a LibTest test so we can prevent regressions in mmap,
the page allocator, and the memory manager.
2021-07-11 19:42:00 +02:00
Gunnar Beutner
75ba74a216 Tests: Build all tests on x86_64
This builds some previously-disabled tests for x86_64.
2021-07-07 15:29:18 +02:00
Andrew Kaster
44a6715584 Tests: TestProcFs cannot assume stdin/stdout/stderr are the same
If someone runs the test with shell redirection going on, or in a way
that changes any of the standard file descriptors this assumption will
not hold. When running from a terminal normally, it is true however.

Instead, check that /proc/self/fd/[0,1,2] are symlinks, and can be
stat-d by verifying that both stat and lstat succeed, and give different
struct stat contents.
2021-06-30 08:18:28 +04:30
Kyle Ambroff-Kao
d173945dad Tests: Add a test for ProcFS fd interaction
Co-authored-by: Tim Schumacher <timschumi@gmx.de>
2021-06-18 10:15:14 +02:00
Ali Mohammad Pur
90de1ded55 Kernel: Ensure that an unveil node with no permission is never accepted
Otherwise nodes inheriting from root may still be accessed with
`access(..., F_OK)`.
Also adds a test case to TestKernelUnveil about this behaviour.
2021-05-29 22:05:34 +02:00
Andrew Kaster
7e905ea201 Tests: Install non-LibTest based Kernel tests into Kernel/Legacy subdir
This makes it easier to run tests we know will work in CI, and ignore
ones that need some help to be repeatable.
2021-05-21 12:05:34 +04:30
Lenny Maiorani
2b64d163cd Tests: static vs non-static constexpr variables
Problem:
- `static` variables consume memory and sometimes are less
  optimizable.
- `static const` variables can be `constexpr`, usually.
- `static` function-local variables require an initialization check
  every time the function is run.

Solution:
- If a global `static` variable is only used in a single function then
  move it into the function and make it non-`static` and `constexpr`.
- Make all global `static` variables `constexpr` instead of `const`.
- Change function-local `static const[expr]` variables to be just
  `constexpr`.
2021-05-19 21:21:03 +01:00
Hediadyoin1
5a8c220101 Kernel: Add a test for multi-region mprotect 2021-05-18 16:50:52 +02:00
Jean-Baptiste Boric
eecf7a2097 LibC: Move mman.h to sys/mman.h
POSIX mandates that it is placed there.
2021-05-14 22:24:02 +02:00
Jean-Baptiste Boric
e16894af5a LibC: Do not include errno.h inside unistd.h
POSIX does not mandate this, therefore let's not do it.
2021-05-14 22:24:02 +02:00
Jean-Baptiste Boric
5a0468c21f Userland: Migrate from arc4random_uniform() to get_random_uniform() 2021-05-14 22:24:02 +02:00
Brian Gianforcaro
fd0dbd1ebf Tests: Establish root Tests directory, move Userland/Tests there
With the goal of centralizing all tests in the system, this is a
first step to establish a Tests sub-tree. It will contain all of
the unit tests and test harnesses for the various components in the
system.
2021-05-06 17:54:28 +02:00
Ben Wiederhake
29eceebdbf Tests: Build automatically, fix compilation errors 2020-08-02 17:15:36 +02:00
Ben Wiederhake
b24cfd36ae Kernel: Demonstrate kernel crash on invalid fcntl 2020-05-03 22:46:28 +02:00
Michael Lelli
58a34fbe09
Kernel: Fix pledge syscall applying new pledges when it fails (#2076)
If the exec promises fail to apply, then the normal promises should
not apply either. Add a test for this fixed functionality.
2020-05-03 00:41:18 +02:00
Brian Gianforcaro
60fc939e81 Tests: Add test case for pthread_cond_timedwait with a timeout.
Add a test case that the timeout argument to pthread_cond_timedwait
works in LibPthread. This change also validates the new support for
timeouts to the futex syscall, as that's how condition variables are
implemented.
2020-04-26 21:31:52 +02:00
Ben Wiederhake
28e1da344d Kernel: Demonstrate race condition in clock_nanosleep
This adds a test for the race condition in clock_nanosleep.
The crux is that clock_nanosleep verifies that the output buffer
is writable *before* sleeping, and writes to it *after* sleeping.
In the meantime, a concurrent thread can make the output buffer
unwritable, e.g. by deallocating it.

This testcase is needlessly complex because pthread_kill is
not implemented yet.  I tried to keep it as simple as possible.

Here is the relevant part of dmesg:
[nanosleep-race-outbuf-munmap(22:22)]: Unblock nanosleep-race-outbuf-munmap(20:20) due to signal
nanosleep-race-outbuf-munmap(20:20) Unrecoverable page fault, write to address 0x02130016
CRASH: Page Fault. Process: nanosleep-race-outbuf-munmap(20)
[nanosleep-race-outbuf-munmap(20:20)]: 0xc01160ff  memcpy +44
[nanosleep-race-outbuf-munmap(20:20)]: 0xc014de64  Kernel::Process::crash(int, unsigned int) +782
[nanosleep-race-outbuf-munmap(20:20)]: 0xc01191b5  illegal_instruction_handler +0
[nanosleep-race-outbuf-munmap(20:20)]: 0xc011965b  page_fault_handler +649
[nanosleep-race-outbuf-munmap(20:20)]: 0xc0117233  page_fault_asm_entry +22
[nanosleep-race-outbuf-munmap(20:20)]: 0xc011616b  copy_to_user +102
[nanosleep-race-outbuf-munmap(20:20)]: 0xc015911f  Kernel::Process::sys(Kernel::Syscall::SC_clock_nanosleep_params const*) +457
[nanosleep-race-outbuf-munmap(20:20)]: 0xc015daad  syscall_handler +1130
[nanosleep-race-outbuf-munmap(20:20)]: 0xc015d597  syscall_asm_entry +29
[nanosleep-race-outbuf-munmap(20:20)]: 0x08048437  main +146
[nanosleep-race-outbuf-munmap(20:20)]: 0x08048573  _start +94

Most importantly, note that it crashes *inside*
Kernel::Process::sys.
Instead, the correct behavior is to return -EFAULT.
2020-03-03 20:13:32 +01:00
Andreas Kling
c44b4d61f3 Kernel: Make Inode::lookup() return a RefPtr<Inode>
Previously this API would return an InodeIdentifier, which meant that
there was a race in path resolution where an inode could be unlinked
in between finding the InodeIdentifier for a path component, and
actually resolving that to an Inode object.

Attaching a test that would quickly trip an assertion before.

Test: Kernel/path-resolution-race.cpp
2020-02-01 10:56:17 +01:00
Andreas Kling
c17f80e720 Kernel: AnonymousVMObject::create_for_physical_range() should fail more
Previously it was not possible for this function to fail. You could
exploit this by triggering the creation of a VMObject whose physical
memory range would wrap around the 32-bit limit.

It was quite easy to map kernel memory into userspace and read/write
whatever you wanted in it.

Test: Kernel/bxvga-mmap-kernel-into-userspace.cpp
2020-01-28 20:48:07 +01:00
Sergey Bugaev
6466c3d750 Kernel: Pass correct permission flags when opening files
Right now, permission flags passed to VFS::open() are effectively ignored, but
that is going to change.

* O_RDONLY is 0, but it's still nicer to pass it explicitly
* POSIX says that binding a Unix socket to a symlink shall fail with EADDRINUSE
2020-01-18 23:51:22 +01:00
Andreas Kling
862b3ccb4e Kernel: Enforce W^X between sys$mmap() and sys$execve()
It's now an error to sys$mmap() a file as writable if it's currently
mapped executable by anyone else.

It's also an error to sys$execve() a file that's currently mapped
writable by anyone else.

This fixes a race condition vulnerability where one program could make
modifications to an executable while another process was in the kernel,
in the middle of exec'ing the same executable.

Test: Kernel/elf-execve-mmap-race.cpp
2020-01-18 23:40:12 +01:00
Andreas Kling
c6e552ac8f Kernel+LibELF: Don't blindly trust ELF symbol offsets in symbolication
It was possible to craft a custom ELF executable that when symbolicated
would cause the kernel to read from user-controlled addresses anywhere
in memory. You could then fetch this memory via /proc/PID/stack

We fix this by making ELFImage hand out StringView rather than raw
const char* for symbol names. In case a symbol offset is outside the
ELF image, you get a null StringView. :^)

Test: Kernel/elf-symbolication-kernel-read-exploit.cpp
2020-01-16 22:11:31 +01:00
Andreas Kling
8c5cd97b45 Kernel: Fix kernel null deref on process crash during join_thread()
The join_thread() syscall is not supposed to be interruptible by
signals, but it was. And since the process death mechanism piggybacked
on signal interrupts, it was possible to interrupt a pthread_join() by
killing the process that was doing it, leading to confusing due to some
assumptions being made by Thread::finalize() for threads that have a
pending joiner.

This patch fixes the issue by making "interrupted by death" a distinct
block result separate from "interrupted by signal". Then we handle that
state in join_thread() and tidy things up so that thread finalization
doesn't get confused by the pending joiner being gone.

Test: Tests/Kernel/null-deref-crash-during-pthread_join.cpp
2020-01-10 19:23:45 +01:00
Andreas Kling
76c20642f0 Kernel: Ignore closed fd's when considering select() unblock
This fixes a null RefPtr deref (which asserts) in the scheduler if a
file descriptor being select()'ed is closed by a second thread while
blocked in select().

Test: Kernel/null-deref-close-during-select.cpp
2020-01-09 12:36:42 +01:00
Andreas Kling
fe9680f0a4 Kernel: Validate PROT_READ and PROT_WRITE against underlying file
This patch fixes some issues with the mmap() and mprotect() syscalls,
neither of whom were checking the permission bits of the underlying
files when mapping an inode MAP_SHARED.

This made it possible to subvert execution of any running program
by simply memory-mapping its executable and replacing some of the code.

Test: Kernel/mmap-write-into-running-programs-executable-file.cpp
2020-01-07 19:32:32 +01:00
Andreas Kling
5387a19268 Kernel: Make Process::file_description() vend a RefPtr<FileDescription>
This encourages callers to strongly reference file descriptions while
working with them.

This fixes a use-after-free issue where one thread would close() an
open fd while another thread was blocked on it becoming readable.

Test: Kernel/uaf-close-while-blocked-in-read.cpp
2020-01-07 15:53:42 +01:00