Commit graph

6448 commits

Author SHA1 Message Date
DrewStratford 2a8de4cdec LibCore: Fix segfault in CArgsParser (#1072)
CArgsParser::parse_next_param did not properly ensure that, when
a param required a following argument, there were enough parameters left to
complete the parse. This meant that params_left could become negative,
avoiding parse_next_param's termination condition, and cause a segfault
when reading from argv with an out of bounds index.

This fixes the check to ensure that we do in fact have the right amount
of parameters and also adds an assertion to ensure that params_left does
not become negative.
2020-01-13 14:52:25 +01:00
Andreas Kling ad5ee27ea9 mv: Use pledge() 2020-01-13 14:51:35 +01:00
Andreas Kling 8ccc2b25c2 cp: Use pledge() 2020-01-13 14:51:18 +01:00
Andreas Kling 56428e764e Applications: Use pledge()
Add some basic pledges to the following apps:

- Calculator
- DisplayProperties
- FontEditor
- HexEditor
- PaintBrush
2020-01-13 14:41:15 +01:00
Andreas Kling 6182a1a71c About: Drop "unix" pledge after connecting to WindowServer 2020-01-13 14:41:15 +01:00
Andreas Kling 6f89557ffc WindowServer: Add "thread" pledge since we need it for wallpapers
Longer-term we should come up with a design where WindowServer doesn't
have to decode untrusted image files.
2020-01-13 14:41:15 +01:00
Andrew Kaster c3be3718cf Demos: Compile LinkDemo as a PIE with interpreter /lib/lib-elf.so 2020-01-13 13:03:30 +01:00
Andrew Kaster 7a7e7c82b5 Kernel: Tighten up exec/do_exec and allow for PT_INTERP iterpreters
This patch changes how exec() figures out which program image to
actually load. Previously, we opened the path to our main executable in
find_shebang_interpreter_for_executable, read the first page (or less,
if the file was smaller) and then decided whether to recurse with the
interpreter instead. We then then re-opened the main executable in
do_exec.

However, since we now want to parse the ELF header and Program Headers
of an elf image before even doing any memory region work, we can change
the way this whole process works. We open the file and read (up to) the
first page in exec() itself, then pass just the page and the amount read
to find_shebang_interpreter_for_executable. Since we now have that page
and the FileDescription for the main executable handy, we can do a few
things. First, validate the ELF header and ELF program headers for any
shenanigans. ELF32 Little Endian i386 only, please. Second, we can grab
the PT_INTERP interpreter from any ET_DYN files, and open that guy right
away if it exists. Finally, we can pass the main executable's and
optionally the PT_INTERP interpreter's file descriptions down to do_exec
and not have to feel guilty about opening the file twice.

In do_exec, we now have a choice. Are we going to load the main
executable, or the interpreter? We could load both, but it'll be way
easier for the inital pass on the RTLD if we only load the interpreter.
Then it can load the main executable itself like any old shared object,
just, the one with main in it :). Later on we can load both of them
into memory and the RTLD can relocate itself before trying to do
anything. The way it's written now the RTLD will get dibs on its
requested virtual addresses being the actual virtual addresses.
2020-01-13 13:03:30 +01:00
Andrew Kaster 046d6a6bbb LibELF: Add methods to validate the ELF and program headers
These will make sure there's no funny business or funny offsets in the
main ELF header or each Program Header. More can still be done (like
validating section headers), but this is a good start
2020-01-13 13:03:30 +01:00
Andrew Kaster fe0eb04a22 Kernel: Overload dbgputstr for char array literals in C++
This just seems like something we should be able to do. The compiler
knows how long my "string literal" is, passing it along manually seems
siilly.
2020-01-13 13:03:30 +01:00
Andrew Kaster 5accedfedb Demos: Remove extra methods/globals from DynamicLib 2020-01-13 13:03:30 +01:00
Andrew Kaster 4cb7c8ea85 LibC: Move even more methods and globals out of crt0.o 2020-01-13 13:03:30 +01:00
Andrew Kaster 9681d41bf0 AK: Add ArmedScopeGuard, a scope guard that can be disarmed 2020-01-13 13:03:30 +01:00
Brian Gianforcaro 4cee441279 Kernel: Combine validate and copy of user mode pointers (#1069)
Right now there is a significant amount of boiler plate code required
to validate user mode parameters in syscalls. In an attempt to reduce
this a bit, introduce validate_read_and_copy_typed which combines the
usermode address check and does the copy internally if the validation
passes. This cleans up a little bit of code from a significant amount
of syscalls.
2020-01-13 11:19:17 +01:00
Brian Gianforcaro 9cac205d67 Kernel: Fix SMAP in setkeymap syscall
It looks like setkeymap was missed when
the SMAP functionality was introduced.

Disable SMAP only in the scope where we
actually read the usermode addresses.
2020-01-13 11:17:10 +01:00
Brian Gianforcaro e9a5b7456e About: Use pledge() 2020-01-13 11:11:18 +01:00
Brian Gianforcaro 02704a73e9 Kernel: Use the templated copy_from_user where possible
Now that the templated version of copy_from_user exists
their is normally no reason to use the version which
takes the number of bytes to copy. Move to the templated
version where possible.
2020-01-13 11:07:39 +01:00
Brian Gianforcaro 46c60fd451 Debugging: Add kernel debugging support
Introduce the 'debug-kernel' script to allow developers to
quickly attach a debugger to the QEMU debug remote. The
setting (-s) is already enabled by ./run today when using
QEMU for virtualisation.

If the system is running under QEMU, the debugger
will break in when the script is run. If you add
the -S option to QEMU it will wait for the debugger
to connect before booting the kernel. This allows
you to debug the init/boot process.

Personally I use cgdb instead of gdb, so I opted
to make the debugger used by the script customizable
via an environment variable.

This change also adds -g3 to the kernel build so that
rich debug symbols are available in the kernel binary.
2020-01-13 11:06:42 +01:00
Brian Gianforcaro 10c1f27b7a LookupServer: Use pledge() 2020-01-13 11:05:52 +01:00
Brian Gianforcaro 1915151116 man: Use pledge() 2020-01-13 11:04:35 +01:00
Brian Gianforcaro f7148c766a more: Use pledge() 2020-01-13 11:04:35 +01:00
Brian Gianforcaro e45a4b0931 md: Use pledge() 2020-01-13 11:04:35 +01:00
Brian Gianforcaro a77da7f245 ls: Use pledge() 2020-01-13 11:04:35 +01:00
Brian Gianforcaro 70defb34e6 tail: Use pledge() 2020-01-13 11:04:35 +01:00
Andreas Kling 0c44a12247 Kernel: read() and write() should EOVERFLOW if (offset+size) overflows 2020-01-12 20:20:17 +01:00
Andreas Kling 20b2bfcafd Kernel: Fix SMAP violation in sys$getrandom() 2020-01-12 20:10:53 +01:00
Andreas Kling 14d4b1058e Kernel: Add a basic lock to FileDescription
Let's prevent two processes sharing a FileDescription from messing with
it at the same time for now.
2020-01-12 20:09:44 +01:00
Sergey Bugaev 9513f54932 Base: Document new chroot abilities 2020-01-12 20:02:11 +01:00
Sergey Bugaev 33c0dc08a7 Kernel: Don't forget to copy & destroy root_directory_for_procfs
Also, rename it to root_directory_relative_to_global_root.
2020-01-12 20:02:11 +01:00
Sergey Bugaev 8ca6e63119 Userland: Support custom programs and mount options in chroot 2020-01-12 20:02:11 +01:00
Sergey Bugaev dd54d13d8d Kernel+LibC: Allow passing mount flags to chroot()
Since a chroot is in many ways similar to a separate root mount, we can also
apply mount flags to it as if it was an actual mount. These flags will apply
whenever the chrooted process accesses its root directory, but not when other
processes access this same directory for the outside. Since it's common to
chdir("/") immediately after chrooting (so that files accessed through the
current directory inherit the same mount flags), this effectively allows one to
apply additional limitations to a process confined inside a chroot.

To this effect, sys$chroot() gains a mount_flags argument (exposed as
chroot_with_mount_flags() in userspace) which can be set to all the same values
as the flags argument for sys$mount(), and additionally to -1 to keep the flags
set for that file system. Note that passing 0 as mount_flags will unset any
flags that may have been set for the file system, not keep them.
2020-01-12 20:02:11 +01:00
Sergey Bugaev fee6d0a3a6 Kernel+Base: Mount root as nodev,nosuid
Then bind-mount /dev and /bin while adding back the appropriate permissions :^)
2020-01-12 20:02:11 +01:00
Sergey Bugaev 1a55264fe6 Userland: Support comments and blank lines in /etc/fstab 2020-01-12 20:02:11 +01:00
Sergey Bugaev 93ff911473 Kernel: Properly propagate bind mount flags
Previously, when performing a bind mount flags other than MS_BIND were ignored.
Now, they're properly propagated the same way a for any other mount.
2020-01-12 20:02:11 +01:00
Sergey Bugaev b620ed25ab Kernel: Simplify Ext2FS mount code path
Instead of looking up device metadata and then looking up a device by that
metadata explicitly, just use VFS::open(). This also means that attempting to
mount a device residing on a MS_NODEV file system will properly fail.
2020-01-12 20:02:11 +01:00
Sergey Bugaev 3393b78623 Kernel: Allow getting a Device from a FileDescription
Like we already do for other kinds of files.
2020-01-12 20:02:11 +01:00
Sergey Bugaev 35b0f10f20 Kernel: Don't dump backtrace on successful exits
This was getting really annoying.
2020-01-12 20:02:11 +01:00
Andreas Kling 198cd77307 Base: Tweak language in pledge(2) man page 2020-01-12 19:08:42 +01:00
Andreas Kling 41376d4662 Kernel: Fix Lock racing to the WaitQueue
There was a time window between releasing Lock::m_lock and calling into
the lock's WaitQueue where someone else could take m_lock and bring two
threads into a deadlock situation.

Fix this issue by holding Lock::m_lock until interrupts are disabled by
either Thread::wait_on() or WaitQueue::wake_one().
2020-01-12 19:04:16 +01:00
Andreas Kling 61e6b1fb7c AK: Run clang-format on Atomic.h
Also use <AK/Types.h> instead of <stddef.h>
2020-01-12 18:45:13 +01:00
Andreas Kling f3eb06a46f Base: Add a man page about pledge(2) 2020-01-12 16:11:12 +01:00
Andreas Kling 8b54ba0d61 Kernel: Dispatch pending signals when returning from a syscall
It was quite easy to put the system into a heavy churn state by doing
e.g "cat /dev/zero".

It was then basically impossible to kill the "cat" process, even with
"kill -9", since signals are only delivered in two conditions:

a) The target thread is blocked in the kernel
b) The target thread is running in userspace

However, since "cat /dev/zero" command spends most of its time actively
running in the kernel, not blocked, the signal dispatch code just kept
postponing actually handling the signal indefinitely.

To fix this, we now check before returning from a syscall if there are
any pending unmasked signals, and if so, we take a dramatic pause by
blocking the current thread, knowing it will immediately be unblocked
by signal dispatch anyway. :^)
2020-01-12 15:04:33 +01:00
Andreas Kling 62a191b59a Kernel: Require "tty" for ioctl() on TTY and MasterPTY
SystemServer now pledges "tty" since it's used when spawning services.
2020-01-12 13:29:51 +01:00
Andreas Kling 35c84504cd IPv4: Require "inet" promise for ioctl() on an IPv4Socket 2020-01-12 13:28:07 +01:00
Andreas Kling a27d2b7b32 chmod: Use pledge() 2020-01-12 13:25:02 +01:00
Andreas Kling 22cf24cba7 ChanViewer: Use pledge()
This app should be ported to LibProtocol, which would allow it to drop
"inet" and "dns" as well.
2020-01-12 13:22:34 +01:00
Andreas Kling e588a41ac9 Browser: Drop "unix" pledge after starting up
We now instantiate a connection to ProtocolServer right away by calling
ResourceLoader::the(). This allows us to drop the "unix" pledge. :^)
2020-01-12 13:20:02 +01:00
0xtechnobabble e12798c0a9 chown: Use pledge() 2020-01-12 12:55:20 +01:00
0xtechnobabble f501014fae Userland: Add the chgrp command
The chgrp command allows the user to easily modify a file's group while
leaving its owner unchanged.
2020-01-12 12:55:20 +01:00
0xtechnobabble 954daaa916 Userland: Add named gid/uid args parsing
This patch makes it so that if a user provides a groupname/username
instead of an id, chown will automatically convert it to a gid/uid
using getgrnam() or getpwnam() respectively.
2020-01-12 12:55:20 +01:00