Commit Graph

1048 Commits

Author SHA1 Message Date
Joshua Abraham ee6493d02e UserScheme: permission check EUID and EGID before proceeding with chown
Fixes redox#1327.
2021-03-20 20:42:02 -05:00
Jeremy Soller 47048102ef Fix typo in ContextList 2021-03-02 19:57:44 -07:00
Jeremy Soller b8e47f6b8f Merge branch 'fix-invalid-grant-state' into 'master'
Fix "Grant should not exist" errors.

See merge request redox-os/kernel!174
2021-03-02 13:30:03 +00:00
4lDO2 031496ff0d Fix "Grant should not exist" errors.
This is done by making sure that when empty() is called on a context,
the grants Arc will be replaced with a new unused Arc, hence
decrementing the refcount. Previously this was only done when the
context was actually reaped, but since there is no guarantee as far as I
am aware about when this must happen, the grants could be completely
leaked, leading to the error.
2021-02-27 15:36:12 +01:00
Jeremy Soller f873fc7e1a Merge branch '4lDO2/kernel-use_gs_for_tls' 2021-02-23 09:21:00 -07:00
Jeremy Soller ba330ffc9a Merge branch 'fix-utf8-userspace-ub' into 'master'
Give schemes a dangling address for empty slices, fixing UB in userspace

See merge request redox-os/kernel!172
2021-02-23 16:17:30 +00:00
4lDO2 ad58ca1de6 Give schemes a dangling address for empty slices.
This allows schemes to avoid checking the length against zero before
constructing a slice from pointer+len that the kernel gave.
Additionally, the address is now non-canonical on x86, meaning that
userspace will fail instead of continuing with UB, if they would ever
forget to check the length.
2021-02-20 17:20:30 +01:00
4lDO2 bdc925d275 Use GS for TLS!
Previously, the kernel used the regular FS segment for Thread-Local
Storage. The problem however, is that userspace code also uses FS for
TLS, meaning that the kernel would have to switch the FS segment between
user and kernel, _upon every syscall_. This is obviously suboptimal for
performance (especially with fast syscalls such as futex, nanosleep, or
yield).

I had to search LLVM for hours, just to find out that the insertion of
the memory load with FS was actually done in the linker, so I added a
flag for that.

I haven't done any proper benchmarking, but the boot process seems to
have gotten much faster!
2021-02-17 14:44:45 +01:00
Jeremy Soller a283160c14 Merge branch 'sysretq-fix2' into 'master'
FIX: Forbid lower-half noncanonical addresses too.

See merge request redox-os/kernel!170
2021-02-17 13:32:26 +00:00
4lDO2 1988583e23 Forbid lower-half noncanonical addresses too. 2021-02-17 13:00:07 +01:00
Jeremy Soller 98af1405e6 Merge branch 'sysretq-fix' into 'master'
Fix mistyped instructions in sysretq

See merge request redox-os/kernel!169
2021-02-15 19:12:05 +00:00
4lDO2 a4b3af34a5 Use correct jump instruction. 2021-02-15 20:05:00 +01:00
4lDO2 c19581282d Use the correct add instruction when popping CS. 2021-02-15 20:02:35 +01:00
Jeremy Soller 2a9b7a0fc8 Merge branch 'sysretq' into 'master'
Use faster sysretq when returning from system calls

See merge request redox-os/kernel!168
2021-02-15 18:59:19 +00:00
4lDO2 8eb58891aa Simplify sysretq code. 2021-02-15 19:53:49 +01:00
4lDO2 5b2df9f504 Document why usermode() can omit rcx check. 2021-02-15 19:53:49 +01:00
4lDO2 ff33090fd0 Check whether RCX is canonical in sysretq. 2021-02-15 19:53:41 +01:00
4lDO2 a183953ee8 Motivate usage of the IST without SWAPGS involved. 2021-02-15 19:53:37 +01:00
4lDO2 a3583a10ce Only swapgs when leaving/entering userspace code. 2021-02-15 19:53:37 +01:00
4lDO2 05db0f5977 Temporarily fix sysretq by swapping gs 4 times.
In order words, it swaps gs both directly at the start of the syscall
handler, then swaps it back, and the at the end of the syscall handler.
I cannot tell for sure why this is necessary, but probably since some
interrupt handler will execute swapgs in the wrong order or something.
2021-02-15 19:53:37 +01:00
4lDO2 1a8016b985 Give NMI, #DF, and #MC handlers a special stack.
This is done by allocating an extra 64 KiB per CPU, and putting it in
the Interrupt Stack Table.
2021-02-15 19:53:37 +01:00
4lDO2 5a638691e0 Treat GS as always pointing to TSS in kernel space. 2021-02-15 19:53:37 +01:00
4lDO2 c913c3be80 Use sysretq in usermode(). 2021-02-15 19:53:24 +01:00
4lDO2 a8dc3fcaf1 Begin using sysretq in the system call handler. 2021-02-15 19:53:01 +01:00
Jeremy Soller 6db78cce24 Use UTF-8 for all paths 2021-02-14 13:45:03 -07:00
Jeremy Soller 11b5e2fe59 Merge branch 'switch_to_safer' into 'master'
Prevent possible UB, and use naked functions correctly.

See merge request redox-os/kernel!167
2021-02-13 22:42:18 +00: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 cd6ede84fe Fix warnings from futex changes 2021-02-13 12:16:55 -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
Jeremy Soller 76d8c1074c Merge branch 'futex-fix' into 'master'
Use physical addresses internally in futex, and fix a context switching data race

See merge request redox-os/kernel!166
2021-02-13 17:52:09 +00:00
4lDO2 6f3fc3a4f4 Make cpu_id_opt non-mutable. 2021-02-03 18:10:39 +01: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
4lDO2 fec8f4aa0c Use physical addresses internally for futexes.
This solves a bug, that allows processes in different address spaces to
be the target of a futex wakeup call, even though that process is in
another address space!
2021-02-03 18:06:42 +01:00
Jeremy Soller 5e10feeaeb Fix whitespace in linker file 2021-01-12 19:59:05 -07:00
Jeremy Soller 6c4c19a95c Move consts to arch 2021-01-12 19:57:42 -07:00
Jeremy Soller ed55b49093 Update aarch64 target to new Rust 2021-01-12 19:57:07 -07: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 ccddabadf7 Make x86 specific dependencies, x86 specific 2021-01-09 20:12:59 -07:00
Jeremy Soller e771e6a4d9 Reduce duplication in context::switch 2020-12-27 20:03:13 -07:00
Jeremy Soller 9033902830 Better messaging about which timer is used 2020-12-23 10:33:09 -07:00
Jeremy Soller 04cc8a2d9c Simplify reserved memory hack 2020-12-23 09:55:03 -07:00
Jeremy Soller 7355ae1671 Hack to ensure kernel is mapped even if it uses reserved memory 2020-12-23 09:46:34 -07:00