Commit Graph

123 Commits

Author SHA1 Message Date
Jeremy Soller 47048102ef Fix typo in ContextList 2021-03-02 19:57:44 -07:00
4lDO2 c913c3be80 Use sysretq in usermode(). 2021-02-15 19:53:24 +01:00
Jeremy Soller 6db78cce24 Use UTF-8 for all paths 2021-02-14 13:45:03 -07:00
4lDO2 a706a0dae4 Rewrite signal_handler_wrapper as single asm block.
The reason for these types of rewrites, is that more recent Rust
compilers have started to deprecate naked functions that consist of more
than only a single asm block, as they can trigger all sorts of UB.
2021-02-13 21:55:40 +01:00
4lDO2 47c3b2269f Fix context switching.
Previously there was a triple fault, due to a combination of reasons
(e.g. rsp and rbp being ordered in the struct and in the assembly).

Now, the locks will be held __all the way until the new context__ has
been switched to, which completely eliminates any possibility that the
"pcid fault" originates here.

While I am unsure whether this will work, this could also be an
opportunity to be able to remove CONTEXT_SWITCH_LOCK fully.
2021-02-13 21:55:40 +01:00
4lDO2 ef4270e473 WIP: Attempt to rewrite switch_to in assembly.
This is due to a warning in more recent compilers, which forbid anything
but a single inline assembly block, in naked functions. It does
unfortunately triple fault right now, but I hope I may be able to fix it
soon.
2021-02-13 21:55:36 +01:00
Jeremy Soller c19bd573b5 Switch Context::grants to RwLock 2021-02-13 13:06:13 -07:00
Jeremy Soller 2611985a38 Switch Context::actions to RwLock 2021-02-13 13:01:20 -07:00
Jeremy Soller bfaf8438a1 Switch Context::files to RwLock 2021-02-13 12:57:53 -07:00
Jeremy Soller 55d2467420 Switch Context::cwd to using RwLock 2021-02-13 12:24:19 -07:00
Jeremy Soller 238702f7d1 Require UTF-8 for context name 2021-02-13 12:16:47 -07:00
Jeremy Soller b9f4a915ea Make context name a RwLock 2021-02-13 11:10:21 -07:00
4lDO2 44527a8340 Fix a very annoying multi_core data race*.
So, when I first introduced io_uring, it was not compiled with the
`multi_core` kernel feature, mainly to make development easier (I
thought). However, since io_uring allows multiple simultaneous system
calls, we cannot longer make the in-kernel contexts block, for example
when receiving a message from a pipe, if there can be multiple such
requests simultaneously.

This has required me to change WaitCondition into allowing multiple
simultaneous tasks; although, it introduces a potential race condition:
since a future can only return Pending and not block directly before
releasing the lock (condvar logic), we need some way to make sure that
nothing happens after the context finds out that it has to wait, and the
actual waiting. If a message is pushed in between, and the waker is
called (Context::unblock), just before it was going to block itself,
then we miss the message, and potentially cause a deadlock.

Fortunately, in order to block and unblock contexts, we need to
exclusively lock the context. So, what we can do to ensure that waking
while running is no longer a no-op, is to introduce a "wake flag", which
is set only if the context is currently running, and Runnable.

But, this still caused all weird kinds of hard-to-debug problems, with
arbitrary CPU exceptions and possibly memory corruption. The reason for
this, is that the context switching logic uses really unsafe operations,
which is why context switching (at the moment) requires an exclusive
lock. Before this commit, it would modify the `running` field after the
lock had been released, which obviously can cause a data race, when the
regular context waker code that is run within a system call, locks the
context but not the global switching lock.

The solution was to make sure that the locks were held, all the way
until the actual switching, which was done in assembly. There can still
be a race condition here, since it modifies memory containing registers
after the lock has been released, even if it may be behind &mut on
another context, which can be UB, but it has not contributed to any
actual bugs... yet.

* I have not yet done that rigorous testing, but it appears to work well
enough, and I have not encountered the bug after like 10 tries.
2021-02-03 18:06:42 +01:00
Jeremy Soller ea6b1e7f8b Update redox_syscall to 0.2.4 2021-01-11 07:01:05 -07:00
Jeremy Soller 334584b3d5 Use rmm::PhysicalAddress and rmm::VirtualAddress directly 2021-01-09 21:16:11 -07:00
Jeremy Soller e771e6a4d9 Reduce duplication in context::switch 2020-12-27 20:03:13 -07:00
Jeremy Soller afa175f778 Merge branch 'jD91mZM2/kernel-remove-brk' into HEAD 2020-08-27 10:26:29 -06:00
Jeremy Soller 853b77e3a4 Unmap owned grants, use owned grants to calculate memory usage 2020-08-25 10:35:55 -06:00
jD91mZM2 922b3d0437 Remove brk 2020-08-15 17:36:50 +02:00
jD91mZM2 f07603902d Replace all llvm_asm! uses with asm! 2020-08-01 14:56:46 +02:00
jD91mZM2 93856b43b9 s/\basm!/llvm_asm!/g 2020-08-01 12:31:56 +02:00
jD91mZM2 34194e2b79 Implement partial funmap-ing for user schemes 2020-07-30 13:08:03 +02:00
jD91mZM2 9eb2aebd43 Implement unmapping multiple whole maps 2020-07-28 11:34:50 +02:00
jD91mZM2 639e603c4f WIP: Add funmap2 2020-07-25 22:29:21 +02:00
jD91mZM2 a811774c58 Add necessary functions for funmap2 2020-07-23 16:45:35 +02:00
jD91mZM2 ccc577b3a1 Abstract over finding nice addresses 2020-07-23 11:22:54 +02:00
jD91mZM2 57c167d2fa Make grants be a BTreeSet 2020-07-22 15:09:28 +02:00
jD91mZM2 310a425c65 Merge branch 'master' into auxv 2020-07-18 12:19:11 +02:00
jD91mZM2 fbdfcd2ba0 WIP: Rewrite interrupts as global assembly
Because the way we were using inline assembly was technically incorrect
and breaking the laws of rust

This *finally* compiles. That doesn't mean it works!
2020-07-11 16:15:25 +02:00
4lDO2 01041a5d8a Implement (mostly) fmap2 for memory: 2020-07-08 20:49:16 +02:00
jD91mZM2 039f7f5c83 Simplify EXEC catching
Instead of having a separate flag, let's reuse STOP_SINGLESTEP :)

I wasn't thinking enough when making this flag!
2020-07-07 14:16:42 +02:00
jD91mZM2 cdcb34486b Keep singlestep across signals 2020-07-07 13:32:10 +02:00
Jeremy Soller 582e3fd8eb Unlock CONTEXT_SWITCH_LOCK after loading registers but before switch 2020-04-21 21:03:17 -06:00
Jeremy Soller c79f308f07 Unlock CONTEXT_SWITCH_LOCK after switch happens 2020-04-21 20:45:15 -06:00
Jeremy Soller 315343be41 Add a way to snapshot context state 2020-04-19 08:46:50 -06:00
Jeremy Soller 123918ed43 Track the namespace that a description was opened from 2020-04-19 08:46:50 -06:00
Jeremy Soller fdf46d8043 Fix multi_core livelocks and add livelock debugging 2020-04-19 08:46:50 -06:00
Jeremy Soller b616fdb067 Keep track of ticks each context uses 2020-02-18 21:16:53 -07:00
Jeremy Soller b892603501 Require mutable context to perform page table modifications 2020-02-10 17:58:44 -07:00
Jeremy Soller 63e2a835e0 Fix clippy.sh script and fix a number of clippy warnings 2019-10-06 11:04:06 -06:00
jD91mZM2 cf0a7620df Add ptrace exit breakpoint
This will let you stop at process exit and inspect it right before the
process dies.
2019-08-15 14:23:54 +02:00
jD91mZM2 ad5f3814fa Add way to ignore signals 2019-07-30 15:54:25 +02:00
jD91mZM2 538ca49ee2 Suggestion: Switch to bitflags 2019-07-26 12:23:21 +02:00
jD91mZM2 3ac1416dba First step for ptrace overhaul 2019-07-24 21:42:33 +02:00
jD91mZM2 a7da393cf5 WIP(ptrace): Better support for signals
Signals now cause an event, and there's a way to continue until the
next signal. I can see this being used for detection of `int3`
although I'm not entirely sure as it may prove being too late to stop
abortion of process.
2019-07-21 19:58:32 +02:00
jD91mZM2 6a3825d408 WIP(ptrace): Only use non-signal stack when using a default handler
This is a curious problem and it's really hard to solve it in a way
that doesn't feel hacky. On one hand, of course you want to be able to
modify and intercept what happens when you use a signal, right? On the
other hand, changes made to the context (especially singlestepping)
while a signal is handled (such as `SIGSTOP`) are not preserved since
the stack is restored after the signal handler was invoked.

I think what we have in this change makes sense anyway, as we don't
really want users modifying registers and other data in the default
signal behavior that occurs **in kernel mode**. Also trying to use
`PTRACE_SINGLESTEP` will set the singlestep flag only if in a
user-mode signal handler, else it will set it on the instruction after
the signal handling, which I guess makes sense since it can't affect
the kernel-mode code that runs the default handler.

I don't know. Help. Pls.
2019-07-20 22:45:33 +02:00
jD91mZM2 8695ecd82b Fix sigaction Undefind Behavior
Rust does not allow a `fn`-pointer to be null. This fixes that, while
luckily doing it in a way that leaves system calls
backwards-compatible :)
2019-07-20 22:41:54 +02:00
jD91mZM2 3d44242407 WIP(ptrace): Finally add stronger security checks 2019-07-20 09:45:07 +02:00
jD91mZM2 6fbb4fbae1 Ptrace memory reading and floating point registers support 2019-07-07 17:07:04 +00:00
Jeremy Soller 788526a3b3 Bare-bones ptracing functionality
Since even a very basic ptrace can be nice to have, I thought I would split
the, perhaps rather big, ptrace project up in multiple PRs to make as few
changes as necessary in each. This PR contains the initial registry modifying
bits and only a very basic security measure. Letting this out to the community
should be good for spotting bugs and maybe getting some hype ;)
2019-07-02 07:38:26 -06:00