Now the DMIDecoder code is more safer, because we don't use raw pointers
or references to objects or data that are located in the physical
address space, so an accidental dereference cannon happen easily.
Instead, we use the PhysicalAddress class to represent those addresses.
Also, the initializer_parser() method is simplified.
syscall_handler was not actually updating the value in regs->eax, so the
gettid() was always returning 85: the value of regs->eax was not
actually updated, and it remained the one from Userland (the value of
SC_gettid).
The syscall_handler was modified to actually get a pointer to
RegisterState, so any changes to it will actually be saved.
NOTE: This was actually more of a compiler optimization:
On the SC_gettid flow, we saved in regs.eax the return value of
sys$gettid(), but the compiler discarded it, since it followed a return.
On a normal flow, the value of regs.eax was reused in
tracer->did_syscall, so the compiler actually updated the value.
set_interrupted_by_death was never called whenever a thread that had
a joiner died, so the joiner remained with the joinee pointer there,
resulting in an assertion fail in JoinBlocker: m_joinee pointed to
a freed task, filled with garbage.
Thread::current->m_joinee may not be valid after the unblock
Properly return the joinee exit value to the joiner thread.
On 32-bit platforms, INT32_MIN == -INT32_MIN, so we can't expect this
to always work:
if (pid < 0)
positive_pid = -pid; // may still be negative!
This happens because the -INT32_MIN expression becomes a long and is
then truncated back to an int.
Fixes#1312.
It was possible to send signals to processes that you were normally not
allowed to send signals to, by calling ioctl(tty, TIOCSPGRP, targetpid)
and then generating one of the TTY-related signals on the calling
process's TTY (e.g by pressing ^C, ^Z, etc.)
This allows a process wich has more than 1 thread to call exec, even
from a thread. This kills all the other threads, but it won't wait for
them to finish, just makes sure that they are not in a running/runable
state.
In the case where a thread does exec, the new program PID will be the
thread TID, to keep the PID == TID in the new process.
This introduces a new function inside the Process class,
kill_threads_except_self which is called on exit() too (exit with
multiple threads wasn't properly working either).
Inside the Lock class, there is the need for a new function,
clear_waiters, which removes all the waiters from the
Process::big_lock. This is needed since after a exit/exec, there should
be no other threads waiting for this lock, the threads should be simply
killed. Only queued threads should wait for this lock at this point,
since blocked threads are handled in set_should_die.
Each process has a 1-level lookup cache for fast repeated lookups of
the same VM region (which tends to be the majority of lookups.)
The cache is used by the following syscalls: munmap, madvise, mprotect
and set_mmap_name.
After a succesful exec(), there could be a stale Region* in the lookup
cache, and the new executable was able to manipulate it using a number
of use-after-free code paths.
Now the ACPI & PCI code is more safer, because we don't use raw pointers
or references to objects or data that are located in the physical
address space, so an accidental dereference cannot happen easily.
Instead, we use the PhysicalAddress class to represent those addresses.
Now we use the GenericInterruptHandler class instead of IRQHandler in
the CPU functions.
This commit adds an include to the ISR stub macros header file.
Also, this commit adds support for IRQ sharing, so when an IRQHandler
will try to register to already-assigned IRQ number, a SharedIRQHandler
will be created to register both IRQHandlers.
Also, the enable() function is now correct and will use the right
registers and values. In addition to that, write_register() and
read_registers() are not relying on identity mapping anymore.
Also, update the class implementation to use PCI::Device class
accordingly.
The create() helper will now search for an IDE controller in the
PCI bus, allowing to simplify the initialize() method.
This class represents a shared interrupt handler. This class will not be
created automatically but only if two IRQ Handlers are sharing the same
IRQ number.
The GenericInterruptHandler class will be used to represent
an abstract interrupt handler. The InterruptManagement class will
represent a centralized component to manage interrupts.
I probably would've done INI config removal in another commit, but it
fit well here because I didn't want to pledge wpath for SystemMenu if I
didn't need to.
Frankly, that's something that I think should be done: allow ConfigFile
to be used read-only.
Each allocation header was tracking its index into the chunk bitmap,
but that index can be computed from the allocation address anyway.
Removing this means that each allocation gets 4 more bytes of memory
and this avoids allocating an extra chunk in many cases. :^)
When committing to a new executable, disown any shared buffers that the
process was previously co-owning.
Otherwise accessing the same shared buffer ID from the new program
would cause the kernel to find a cached (and stale!) reference to the
previous program's VM region corresponding to that shared buffer,
leading to a Region* use-after-free.
Fixes#1270.
Since we're gonna throw away these stacks at the end of exec anyway,
we might as well disable profiling before starting to mess with the
process page tables. One less weird situation to worry about in the
sampling code.
Linux creates holes in block lists for all-zero content. This is very
reasonable and we can now handle that situation as well.
Note that we're not smart enough to generate these holes ourselves yet,
but now we can at least read from such files.
The kernel sampling profiler will walk thread stacks during the timer
tick handler. Since it's not safe to trigger page faults during IRQ's,
we now avoid this by checking the page tables manually before accessing
each stack location.
We're not equipped to deal with page faults during an IRQ handler,
so add an assertion so we can immediately tell what's wrong.
This is why profiling sometimes hangs the system -- walking the stack
of the profiled thread causes a page fault and things fall apart.
If we get an -ENOENT when resolving the target because of some part, that is not
the very last part, missing, we should just return the error instead of panicking
later :^)
To test:
$ mkdir /tmp/foo/
$ mv /tmp/foo/ /tmp/bar/
Related to https://github.com/SerenityOS/serenity/issues/1253
This is apparently a special case unlike any other, so let's handle it
directly in VFS::mkdir() instead of adding an alternative code path into
VFS::resolve_path().
Fixes https://github.com/SerenityOS/serenity/issues/1253
Anonymous VM objects should never have null entries in their physical
page list. Instead, "empty" or untouched pages should refer to the
shared zero page.
Fixes#1237.
This will allow us to run the system menu as any user. It will also
enable further lockdown of the WindowServer process since it should no
longer need to pledge proc and exec. :^)
Note that this program is not finished yet.
Work towards #1231.
Process teardown is divided into two main stages: finalize and reap.
Finalization happens in the "Finalizer" kernel and runs with interrupts
enabled, allowing destructors to take locks, etc.
Reaping happens either in sys$waitid() or in the scheduler for orphans.
The more work we can do in finalization, the better, since it's fully
pre-emptible and reduces the amount of time the system runs without
interrupts enabled.
Replace Process::m_being_inspected with an inspector reference count.
This prevents an assertion from firing when inspecting the same process
in /proc from multiple processes at the same time.
It was trivially reproducible by opening multiple FileManagers.
This patch adds NotificationServer, which runs as the "notify" user
and provides an IPC API for desktop notifications.
LibGUI gains the GUI::Notification class for showing notifications.
NotificationServer is spawned on demand and will unspawn after
dimissing all visible notifications. :^)
Finally, this also comes with a small /bin/notify utility.
This was actually rather painless and straightforward. WindowServer now
runs as the "window" user. Users in the "window" group can connect to
it via the socket in /tmp/portal/window as usual.
This mechanism wasn't actually used to create any WeakPtr<Process>.
Such pointers would be pretty hard to work with anyway, due to the
multi-step destruction ritual of Process.
A 16-bit refcount is just begging for trouble right nowl.
A 32-bit refcount will be begging for trouble later down the line,
so we'll have to revisit this eventually. :^)
This patch adds a globally shared zero-filled PhysicalPage that will
be mapped into every slot of every zero-filled AnonymousVMObject until
that page is written to, achieving CoW-like zero-filled pages.
Initial testing show that this doesn't actually achieve any sharing yet
but it seems like a good design regardless, since it may reduce the
number of page faults taken by programs.
If you look at the refcount of MM.shared_zero_page() it will have quite
a high refcount, but that's just because everything maps it everywhere.
If you want to see the "real" refcount, you can build with the
MAP_SHARED_ZERO_PAGE_LAZILY flag, and we'll defer mapping of the shared
zero page until the first NP read fault.
I've left this behavior behind a flag for future testing of this code.
This was only used by HashTable::dump() which I used when doing the
first HashTable implementation. Removing this allows us to also remove
most includes of <AK/kstdio.h>.
Warnings fixed:
* SC2086: Double quote to prevent globbing and word splitting.
* SC2006: Use $(...) notation instead of legacy backticked `...`
* SC2039: In POSIX sh, echo flags are undefined
* SC2209: Use var=$(command) to assign output (or quote to assign string)
* SC2164: Use 'cd ... || exit' or 'cd ... || return' in case cd fails
* SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.
* SC2034: i appears unused. Verify use (or export if used externally)
* SC2046: Quote this to prevent word splitting.
* SC2236: Use -z instead of ! -n.
There are still a lot of warnings in Kernel/run about:
- SC2086: Double quote to prevent globbing and word splitting.
However, splitting on space is intentional in this case, and not trivial to
change. Therefore ignore the warning for now - but we should fix this in
the future.