Commit graph

112 commits

Author SHA1 Message Date
Andreas Kling
54f421e170 Kernel: Clear coredump metadata on exec()
If for some reason a process wants to exec after saving some coredump
metadata, we should just throw away the data.
2021-01-23 09:41:11 +01:00
Andreas Kling
19d3f8cab7 Kernel+LibC: Turn errno codes into a strongly typed enum
..and allow implicit creation of KResult and KResultOr from ErrnoCode.
This means that kernel functions that return those types can finally
do "return EINVAL;" and it will just work.

There's a handful of functions that still deal with signed integers
that should be converted to return KResults.
2021-01-20 23:20:02 +01:00
Tom
1d621ab172 Kernel: Some futex improvements
This adds support for FUTEX_WAKE_OP, FUTEX_WAIT_BITSET, FUTEX_WAKE_BITSET,
FUTEX_REQUEUE, and FUTEX_CMP_REQUEUE, as well well as global and private
futex and absolute/relative timeouts against the appropriate clock. This
also changes the implementation so that kernel resources are only used when
a thread is blocked on a futex.

Global futexes are implemented as offsets in VMObjects, so that different
processes can share a futex against the same VMObject despite potentially
being mapped at different virtual addresses.
2021-01-17 20:30:31 +01:00
Andreas Kling
992f513ad2 Kernel: Limit exec arguments and environment to 1/8th of stack each
This sort-of matches what some other systems do and seems like a
generally sane thing to do instead of allowing programs to spawn a
child with a nearly full stack.
2021-01-17 18:29:56 +01:00
Andreas Kling
bf0719092f Kernel+Userland: Remove shared buffers (shbufs)
All users of this mechanism have been switched to anonymous files and
passing file descriptors with sendfd()/recvfd().

Shbufs got us where we are today, but it's time we say good-bye to them
and welcome a much more idiomatic replacement. :^)
2021-01-17 09:07:32 +01:00
Brendan Coles
1fa9d9dd68 Kernel: execve: find_elf_interpreter_for_executable: Fix dbgln 2021-01-16 22:36:46 +01:00
Linus Groh
1ccc2e6482 Kernel: Store process arguments and environment in coredumps
Currently they're only pushed onto the stack but not easily accessible
from the Process class, so this adds a Vector<String> for both.
2021-01-15 23:26:47 +01:00
Andreas Kling
64b0d89335 Kernel: Make Process::allocate_region*() return KResultOr<Region*>
This allows region allocation to return specific errors and we don't
have to assume every failure is an ENOMEM.
2021-01-15 19:10:30 +01:00
Lenny Maiorani
e6f907a155 AK: Simplify constructors and conversions from nullptr_t
Problem:
- Many constructors are defined as `{}` rather than using the ` =
  default` compiler-provided constructor.
- Some types provide an implicit conversion operator from `nullptr_t`
  instead of requiring the caller to default construct. This violates
  the C++ Core Guidelines suggestion to declare single-argument
  constructors explicit
  (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c46-by-default-declare-single-argument-constructors-explicit).

Solution:
- Change default constructors to use the compiler-provided default
  constructor.
- Remove implicit conversion operators from `nullptr_t` and change
  usage to enforce type consistency without conversion.
2021-01-12 09:11:45 +01:00
Andreas Kling
5dafb72370 Kernel+Profiler: Make profiling per-process and without core dumps
This patch merges the profiling functionality in the kernel with the
performance events mechanism. A profiler sample is now just another
perf event, rather than a dedicated thing.

Since perf events were already per-process, this now makes profiling
per-process as well.

Processes with perf events would already write out a perfcore.PID file
to the current directory on death, but since we may want to profile
a process and then let it continue running, recorded perf events can
now be accessed at any time via /proc/PID/perf_events.

This patch also adds information about process memory regions to the
perfcore JSON format. This removes the need to supply a core dump to
the Profiler app for symbolication, and so the "profiler coredump"
mechanism is removed entirely.

There's still a hard limit of 4MB worth of perf events per process,
so this is by no means a perfect final design, but it's a nice step
forward for both simplicity and stability.

Fixes #4848
Fixes #4849
2021-01-11 11:36:00 +01:00
Itamar
f259d96871 Kernel: Avoid collision between dynamic loader and main program
When loading non position-independent programs, we now take care not to
load the dynamic loader at an address that collides with the location
the main program wants to load at.

Fixes #4847.
2021-01-10 22:04:43 +01:00
Itamar
40a8159c62 Kernel: Plumb the elf header of the main program down to Process::load
This will enable us to take the desired load address of non-position
independent programs into account when randomizing the load address
of the dynamic loader.
2021-01-10 22:04:43 +01:00
William Marlow
747e8de96a Kernel+Loader.so: Allow dynamic executables without an interpreter
Commit a3a9016701 removed the PT_INTERP header
from Loader.so which cleaned up some kernel code in execve. Unfortunately
it prevents Loader.so from being run as an executable
2021-01-03 19:45:16 +01:00
Andreas Kling
5dae85afe7 Kernel: Pass "shared" flag to Region constructor
Before this change, we would sometimes map a region into the address
space with !is_shared(), and then moments later call set_shared(true).

I found this very confusing while debugging, so this patch makes us pass
the initial shared flag to the Region constructor, ensuring that it's in
the correct state by the time we first map the region.
2021-01-02 16:57:31 +01:00
Tom
e87eaf5df0 Kernel: Fix memory corruption when rolling back regions in execve
We need to free the regions before reverting the paging scope to the
original one when rolling back changes due to an error. This fixes
silent memory corruption.
2021-01-01 23:43:44 +01:00
Tom
bf9be3ec01 Kernel: More gracefully handle out-of-memory when creating PageDirectory 2021-01-01 23:43:44 +01:00
Tom
476f17b3f1 Kernel: Merge PurgeableVMObject into AnonymousVMObject
This implements memory commitments and lazy-allocation of committed
memory.
2021-01-01 23:43:44 +01:00
Andrew Kaster
a3a9016701 DynamicLoader: Tell the linker to not add a PT_INTERP header
Use the GNU LD option --no-dynamic-linker. This allows uncommenting some
code in the Kernel that gets upset if your ELF interpreter has its own
interpreter.
2021-01-01 02:12:28 +01:00
Andreas Kling
1cfdaf96c4 Kernel: Reset the process dumpable flag on successful non-setid exec
Once we've committed to a new memory layout and non-setid credentials,
we can reset the dumpable flag.
2020-12-26 01:31:24 +01:00
Andreas Kling
82f86e35d6 Kernel+LibC: Introduce a "dumpable" flag for processes
This new flag controls two things:
- Whether the kernel will generate core dumps for the process
- Whether the EUID:EGID should own the process's files in /proc

Processes are automatically made non-dumpable when their EUID or EGID is
changed, either via syscalls that specifically modify those ID's, or via
sys$execve(), when a set-uid or set-gid program is executed.

A process can change its own dumpable flag at any time by calling the
new sys$prctl(PR_SET_DUMPABLE) syscall.

Fixes #4504.
2020-12-25 19:35:55 +01:00
Andreas Kling
89d3b09638 Kernel: Allocate new main thread stack before committing to exec
If the allocation fails (e.g ENOMEM) we want to simply return an error
from sys$execve() and continue executing the current executable.

This patch also moves make_userspace_stack_for_main_thread() out of the
Thread class since it had nothing in particular to do with Thread.
2020-12-25 16:22:01 +01:00
Andreas Kling
2f1712cc29 Kernel: Move ELF auxiliary vector building out of Process class
Process had a couple of members whose only purpose was holding on to
some temporary data while building the auxiliary vector. Remove those
members and move the vector building to a free function in execve.cpp
2020-12-25 15:23:35 +01:00
Andreas Kling
40e9edd798 LibELF: Move AuxiliaryValue into the ELF namespace 2020-12-25 14:48:30 +01:00
Andreas Kling
6c9a6bea1e Kernel+LibELF: Abort ELF executable load sooner when something fails
Make it possible to bail out of ELF::Image::for_each_program_header()
and then do exactly that if something goes wrong during executable
loading in the kernel.

Also make the errors we return slightly more nuanced than just ENOEXEC.
2020-12-25 14:42:42 +01:00
Andreas Kling
791b32e3c6 Kernel: Remove an unnecessary cast in sys$execve() 2020-12-25 14:16:35 +01:00
Andreas Kling
9c640e67ac Kernel: Don't fetch full inode metadata in sys$execve()
We only need the size, so let's not fetch all the metadata.
2020-12-25 14:15:33 +01:00
Andreas Kling
c3eddbcb49 Kernel: Add back missing ELF::Image validity check
If the image is not a valid ELF we should just fail ASAP.
2020-12-25 14:13:44 +01:00
Andreas Kling
4986f268a5 Kernel: Convert dbg() => dbgln() in sys$execve() 2020-12-25 12:51:35 +01:00
Andreas Kling
09129782de Kernel: Simplify ELF loading logic in sys$execve() somewhat
Get rid of the lambda functions and put the logic inline in the program
header traversal loop instead. This makes the code quite a bit shorter
and hopefully makes it easier to see what's going on.
2020-12-25 02:33:57 +01:00
Andreas Kling
7551a66f73 Kernel+LibELF: Move sys$execve()'s loading logic from LibELF to Kernel
It was really weird that ELF loading was performed by the ELF::Loader
class instead of just being done by the kernel itself. This patch moves
all the layout logic from ELF::Loader over to sys$execve().

The kernel no longer cares about ELF::Loader and instead only uses an
ELF::Image as an interpreting wrapper around executables.
2020-12-25 01:22:55 +01:00
Itamar
0cb636078a Kernel+LibELF: Allow Non ET_DYN executables to have an interpreter 2020-12-24 21:34:51 +01:00
Andreas Kling
1e21d49e86 Kernel: Fix wrong-looking overflow check in sys$execve()
This was harmless since sizeof(length) and sizeof(strings) are both 4
on x86 but let's check the right things regardless.
2020-12-23 20:34:22 +01:00
Lenny Maiorani
765936ebae
Everywhere: Switch from (void) to [[maybe_unused]] (#4473)
Problem:
- `(void)` simply casts the expression to void. This is understood to
  indicate that it is ignored, but this is really a compiler trick to
  get the compiler to not generate a warning.

Solution:
- Use the `[[maybe_unused]]` attribute to indicate the value is unused.

Note:
- Functions taking a `(void)` argument list have also been changed to
  `()` because this is not needed and shows up in the same grep
  command.
2020-12-21 00:09:48 +01:00
Andreas Kling
34e9df3c5e Kernel: Randomize memory location of the dynamic loader :^)
This should make it a little bit harder for those who would mess with
our loader.
2020-12-20 18:49:24 +01:00
Andreas Kling
9bf02c32c0 Kernel: Activate SUID/SGID credentials earlier in sys$execve()
Switch on the new credentials before loading the new executable into
memory. This ensures that attempts to ptrace() the program from an
unprivileged process will fail.

This covers one bug that was exploited in the 2020 HXP CTF:
https://hxp.io/blog/79/hxp-CTF-2020-wisdom2/

Thanks to yyyyyyy for finding the bug! :^)
2020-12-20 18:49:18 +01:00
Andreas Kling
e5eda151b4 Kernel: Silence debug spam when running dynamically linked programs 2020-12-20 16:06:39 +01:00
Tom
c4176b0da1 Kernel: Fix Lock race causing infinite spinning between two threads
We need to account for how many shared lock instances the current
thread owns, so that we can properly release such references when
yielding execution.

We also need to release the process lock when donating.
2020-12-16 23:38:17 +01:00
Itamar
efe4da57df Loader: Stabilize loader & Use shared libraries everywhere :^)
The dynamic loader is now stable enough to be used everywhere in the
system - so this commit does just that.
No More .a Files, Long Live .so's!
2020-12-14 23:05:53 +01:00
Itamar
5b87904ab5 Kernel: Add ability to load interpreter instead of main program
When the main executable needs an interpreter, we load the requested
interpreter program, and pass to it an open file decsriptor to the main
executable via the auxiliary vector.

Note that we do not allocate a TLS region for the interpreter.
2020-12-14 23:05:53 +01:00
Andreas Kling
97d789c75b Kernel: Fix null dereference when execve'ing ELF without PT_TLS header
Fixes #4387.
2020-12-11 22:59:46 +01:00
Andrew Kaster
3f808b0dda LibELF+Kernel: Validate program headers in Image::parse
This should catch more malformed ELF files earlier than simply
checking the ELF header alone. Also change the API of
validate_program_headers to take the interpreter_path by pointer. This
makes it less awkward to call when we don't care about the interpreter,
and just want the validation.
2020-12-01 09:58:21 +01:00
Tom
046d6855f5 Kernel: Move block condition evaluation out of the Scheduler
This makes the Scheduler a lot leaner by not having to evaluate
block conditions every time it is invoked. Instead evaluate them as
the states change, and unblock threads at that point.

This also implements some more waitid/waitpid/wait features and
behavior. For example, WUNTRACED and WNOWAIT are now supported. And
wait will now not return EINTR when SIGCHLD is delivered at the
same time.
2020-11-30 13:17:02 +01:00
Andreas Kling
086522537e Kernel: Don't leak ref on executable inode in sys$execve()
We were leaking a ref on the executed inode in successful calls to
sys$execve(). This meant that once a binary had ever been executed,
it was impossible to remove it from the file system.

The execve system call is particularly finicky since the function
does not return normally on success, so extra care must be taken to
ensure nothing is kept alive by stack variables.

There is a big NOTE comment about this, and yet the bug still got in.
It would be nice to enforce this, but I'm unsure how.
2020-11-23 16:08:42 +01:00
Tom
1e2e3eed62 Kernel: Fix a few deadlocks with Thread::m_lock and g_scheduler_lock
g_scheduler_lock cannot safely be acquired after Thread::m_lock
because another processor may already hold g_scheduler_lock and wait
for the same Thread::m_lock.
2020-10-26 08:57:25 +01:00
Andreas Kling
1d96ecf148 Everywhere: Add missing <AK/TemporaryChange.h> includes
Don't rely on HashTable.h pulling this in.
2020-10-15 23:49:53 +02:00
Linus Groh
bcfc6f0c57 Everywhere: Fix more typos 2020-10-03 12:36:49 +02:00
Andreas Kling
b058852c62 Kernel: Fix overly eager fd closing in sys$execve()
When obeying FD_CLOEXEC, we don't need to explicitly call close() on
all the FileDescriptions. We can just clear them out from the process
fd table. ~FileDescription() will call close() anyway.

This fixes an issue where TelnetServer would shut down accepted sockets
when exec'ing a shell for them. Since the parent process still has the
socket open, we should not force-close it. Just let go.
2020-09-28 22:40:44 +02:00
Andreas Kling
0930e2323b Kernel: Remove unnecessary capture in sys$execve() 2020-09-28 22:24:27 +02:00
Luke
68b361bd21 Kernel: Return ENOMEM in more places
There are plenty of places in the kernel that aren't
checking if they actually got their allocation.

This fixes some of them, but definitely not all.

Fixes #3390
Fixes #3391

Also, let's make find_one_free_page() return nullptr
if it doesn't get a free index. This stops the kernel
crashing when out of memory and allows memory purging
to take place again.

Fixes #3487
2020-09-16 20:38:19 +02:00
Tom
c8d9f1b9c9 Kernel: Make copy_to/from_user safe and remove unnecessary checks
Since the CPU already does almost all necessary validation steps
for us, we don't really need to attempt to do this. Doing it
ourselves doesn't really work very reliably, because we'd have to
account for other processors modifying virtual memory, and we'd
have to account for e.g. pages not being able to be allocated
due to insufficient resources.

So change the copy_to/from_user (and associated helper functions)
to use the new safe_memcpy, which will return whether it succeeded
or not. The only manual validation step needed (which the CPU
can't perform for us) is making sure the pointers provided by user
mode aren't pointing to kernel mappings.

To make it easier to read/write from/to either kernel or user mode
data add the UserOrKernelBuffer helper class, which will internally
either use copy_from/to_user or directly memcpy, or pass the data
through directly using a temporary buffer on the stack.

Last but not least we need to keep syscall params trivial as we
need to copy them from/to user mode using copy_from/to_user.
2020-09-13 21:19:15 +02:00