This allows us to get rid of an include to LibC/sys/ttydefaults.h in the
Kernel TTY implementation.
Also, move ttydefchars static const struct to another file called
Kernel/API/ttydefaultschars.h, so it could be used too in the Kernel TTY
implementation without the need to include anything from LibC.
This header has always been fundamentally a Kernel API file. Move it
where it belongs. Include it directly in Kernel files, and make
Userland applications include it via sys/ioctl.h rather than directly.
Our implementation for Jails resembles much of how FreeBSD jails are
working - it's essentially only a matter of using a RefPtr in the
Process class to a Jail object. Then, when we iterate over all processes
in various cases, we could ensure if either the current process is in
jail and therefore should be restricted what is visible in terms of
PID isolation, and also to be able to expose metadata about Jails in
/sys/kernel/jails node (which does not reveal anything to a process
which is in jail).
A lifetime model for the Jail object is currently plain simple - there's
simpy no way to manually delete a Jail object once it was created. Such
feature should be carefully designed to allow safe destruction of a Jail
without the possibility of releasing a process which is in Jail from the
actual jail. Each process which is attached into a Jail cannot leave it
until the end of a Process (i.e. when finalizing a Process). All jails
are kept being referenced in the JailManagement. When a last attached
process is finalized, the Jail is automatically destroyed.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
The obsolete ttyname and ptsname syscalls are removed.
LibC doesn't rely on these anymore, and it helps simplifying the Kernel
in many places, so it's an overall an improvement.
In addition to that, /proc/PID/tty node is removed too as it is not
needed anymore by userspace to get the attached TTY of a process, as
/dev/tty (which is already a character device) represents that as well.
Function-local `static constexpr` variables can be `constexpr`. This
can reduce memory consumption, binary size, and offer additional
compiler optimizations.
These changes result in a stripped x86_64 kernel binary size reduction
of 592 bytes.
Previously we would crash the process immediately when a promise
violation was found during a syscall. This is error prone, as we
don't unwind the stack. This means that in certain cases we can
leak resources, like an OwnPtr / RefPtr tracked on the stack. Or
even leak a lock acquired in a ScopeLockLocker.
To remedy this situation we move the promise violation handling to
the syscall handler, right before we return to user space. This
allows the code to follow the normal unwind path, and grantees
there is no longer any cleanup that needs to occur.
The Process::require_promise() and Process::require_no_promises()
functions were modified to return ErrorOr<void> so we enforce that
the errors are always propagated by the caller.
This change lays the foundation for making the require_promise return
an error hand handling the process abort outside of the syscall
implementations, to avoid cases where we would leak resources.
It also has the advantage that it makes removes a gs pointer read
to look up the current thread, then process for every syscall. We
can instead go through the Process this pointer in most cases.
It looks like type types are small enough that there is no padding.
So there didn't happen to be an info leak here, but lets zero initialize
just to be on the safe side, and make auditing easier.
This fixes at least half of our LibC includes in the kernel. The source
of truth for errno codes and their description strings now lives in
Kernel/API/POSIX/errno.h as an enumeration, which LibC includes.
We now use AK::Error and AK::ErrorOr<T> in both kernel and userspace!
This was a slightly tedious refactoring that took a long time, so it's
not unlikely that some bugs crept in.
Nevertheless, it does pass basic functionality testing, and it's just
real nice to finally see the same pattern in all contexts. :^)
Found due to smelly code in InodeFile::absolute_path.
In particular, this replaces the following misleading methods:
File::absolute_path
This method *never* returns an actual path, and if called on an
InodeFile (which is impossible), it would VERIFY_NOT_REACHED().
OpenFileDescription::try_serialize_absolute_path
OpenFileDescription::absolute_path
These methods do not guarantee to return an actual path (just like the
other method), and just like Custody::absolute_path they do not
guarantee accuracy. In particular, just renaming the method made a
TOCTOU bug obvious.
The new method signatures use KResultOr, just like
try_serialize_absolute_path() already did.
Some ports (like `bc` with history enabled) sensibly set the termios
character size to 8 bits.
Previously, we left the character size value (given by the bitmask
CSIZE) as zero by default (meaning 5 bits per character), and returned
ENOTIMPL whenever someone modified it. This was dumb.
This has several benefits:
1) We no longer just blindly derefence a null pointer in various places
2) We will get nicer runtime error messages if the current process does
turn out to be null in the call location
3) GCC no longer complains about possible nullptr dereferences when
compiling without KUBSAN
Now that all KResult and KResultOr are used consistently throughout the
kernel, it's no longer necessary to return negative error codes.
However, we were still doing that in some places, so let's fix all those
(bugs) by removing the minuses. :^)
In preparation for modifying the Kernel IOCTL API to return KResult
instead of int, we need to fix this ioctl to an argument to receive
it's return value, instead of using the actual function return value.
It's easy to forget the responsibility of validating and safely copying
kernel parameters in code that is far away from syscalls. ioctl's are
one such example, and bugs there are just as dangerous as at the root
syscall level.
To avoid this case, utilize the AK::Userspace<T> template in the ioctl
kernel interface so that implementors have no choice but to properly
validate and copy ioctl pointer arguments.
These small changes fix the remaining warnings that come up during
kernel compilation with Clang. These specific fixes were for benign
things: unused lambda captures and braces around scalar initializers.
The `File::can_write` mechanism lets us check that writes won't block,
meaning some bytes can be immediately written to the underlying device.
This means calling `File::write` in a situation where no data could be
written is a logic error, which we `VERIFY()` in `Process::do_write()`.
TTY, in particular, processes the write in 256-byte buffered chunks.
Previously, we would assert that none of these sub-writes returned zero.
This was a logic error, as this rejected some successful writes. For
example, if there was exactly enough free space in `SlavePty`'s internal
buffer for the previous sub-write to complete fully. This made it
impossible to perform writes larger than `SlavePty`'s internal buffer.
Note that it's not an issue if `on_tty_write` returns zero, as partial
writes are handled correctly by the `buffer.read_buffered` helper. We
won't spin in a loop trying to write to a full buffer.
Fixes#8090
Previously the VirtualConsole::on_tty_write() method would return an
incorrect value when an error had occurred. This prompted me to
update the TTY subsystem to use KResultOr<size_t> everywhere.
Previously, we would echo characters back just as they were passed to
us, even in canonical mode. This caused newlines to not work correctly
in some programs.
Fixes#7802
I introduced a regression in #7184 where `TTY` would report 1 byte read
in canonical mode even if we had no more characters left. This was
caused by counting the '\0' that denotes EOF into the number of
characters that were read.
The fix was simple: exclude the EOF character from the number of bytes.
This still wouldn't be correct by itself, as the EOF and EOL control
characters could change between when the data was written to the TTY and
when it is read. We fix this by signaling out-of-band whether something
is a special character. End-of-file markers have a value of zero and
have their special bits set. Any other bytes with a special flag are
treated as line endings. This is possible, as POSIX doesn't allow
special characters to be 0.
Fixes#7419
Fixes a bug where TTY::write will attempt to write into the underlying
device but will not acknowledge the result of that write, instead
assuming that the write fully completed.
This commit adds support for the various ECHO* lflags and fixes some
POSIX conformance issues around newline handling. Also included are
error messages when setting not implemented settings.
This non-POSIX header is used in Linux/BSD systems for storing the
default termios settings. This lets us setup new TTYs' `m_termios.c_cc`
in a nicer way than using a magic string.
By constraining two implementations, the compiler will select the best
fitting one. All this will require is duplicating the implementation and
simplifying for the `void` case.
This constraining also informs both the caller and compiler by passing
the callback parameter types as part of the constraint
(e.g.: `IterationFunction<int>`).
Some `for_each` functions in LibELF only take functions which return
`void`. This is a minimal correctness check, as it removes one way for a
function to incompletely do something.
There seems to be a possible idiom where inside a lambda, a `return;` is
the same as `continue;` in a for-loop.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
Added a dummy TIOCSTI ioctl placeholder. This is a dangerous ioctl that
can be used to inject input into a tty. Added for compatibility. Always
fails with EIO.