POSIX explicitly allows providing nullptr's, and our __pthread_*() implementation
stores and calls the provided functions as-is, without checking for nullptr.
This bug is a good example why copy-paste code should eventually be eliminated
from the code base: Apparently the code was copied from read.cpp before
c6027ed7cc, so the same bug got introduced here.
To recap: A malicious program can ask the Kernel to prepare sys-ing to
a huge amount of iovecs. The Kernel must first copy all the vector locations
into 'vecs', and before that allocates an arbitrary amount of memory:
vecs.resize(iov_count);
This can cause Kernel memory exhaustion, triggered by any malicious userland
program.
If the cursor Y position is < 0 in content coordinate space, we should
always map that to the first line of the file.
This fixes unexpected cursor behavior when dragging the selection above
the top of the document.
This removes some hard references to the toolchain, some unnecessary
uses of an external install command, and disables a -Werror flag (for
the time being) - only if run inside serenity.
With this, we can build and link the kernel :^)
This required a bit of rearchitecture, as pthread_atfork() required a
mutex, and duplicating a mutex impl for it was silly.
As such, this patch moves some standalone bits of pthread into LibC and
uses those to implement atfork().
It should be noted that for programs that don't use atfork(), this
mechanism only costs two atomic loads (as opposed to the normal mutex
lock+unlock) :^)
This implementation is pretty damn dumb, and probably has more bugs than
features.
But for the time being, it seems to work. however, we should definitely
replace it with a good implementation sometime very soon :^)
Running 'ninja install && ninja image && ninja run` is kind of
annoying. I got tired, and came up with this instead, which does the
right thing and I don't have to type out the incantation.
KASAN is a dynamic analysis tool that finds memory errors. It focuses
mostly on finding use-after-free and out-of-bound read/writes bugs.
KASAN works by allocating a "shadow memory" region which is used to store
whether each byte of memory is safe to access. The compiler then instruments
the kernel code and a check is inserted which validates the state of the
shadow memory region on every memory access (load or store).
To fully integrate KASAN into the SerenityOS kernel we need to:
a) Implement the KASAN interface to intercept the injected loads/stores.
void __asan_load*(address);
void __asan_store(address);
b) Setup KASAN region and determine the shadow memory offset + translation.
This might be challenging since Serenity is only 32bit at this time.
Ex: Linux implements kernel address -> shadow address translation like:
static inline void *kasan_mem_to_shadow(const void *addr)
{
return ((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
+ KASAN_SHADOW_OFFSET;
}
c) Integrating KASAN with Kernel allocators.
The kernel allocators need to be taught how to record allocation state
in the shadow memory region.
This commit only implements the initial steps of this long process:
- A new (default OFF) CMake build flag `ENABLE_KERNEL_ADDRESS_SANITIZER`
- Stubs out enough of the KASAN interface to allow the Kernel to link clean.
Currently the KASAN kernel crashes on boot (triple fault because of the crash
in strlen other sanitizer are seeing) but the goal here is to just get started,
and this should help others jump in and continue making progress on KASAN.
References:
* ASAN Paper: https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37752.pdf
* KASAN Docs: https://github.com/google/kasan
* NetBSD KASAN Blog: https://blog.netbsd.org/tnf/entry/kernel_address_sanitizer_part_3
* LWN KASAN Article: https://lwn.net/Articles/612153/
* Tracking Issue #5351
We need to first deliver the mouse event and possibly the double click
event and record these facts. Then, we need to iterate all global
tracking listeners and deliver the mouse event (but not the double
click event) to any such listener, unless they already had these
events delivered.
Fixes#4703
There is no reason to call a getter without observing the result, doing
so indicates an error in the code. Mark these methods as [[nodiscard]]
to find these cases.
There is no reason to call a getter without observing the result, doing
so indicates an error in the code. Mark these methods as [[nodiscard]]
to find these cases.
`UserOrKernelBuffer` objects should always be observed when created, in
turn there is no reason to call a getter without observing the result.
Doing either of these indicates an error in the code. Mark these methods
as [[nodiscard]] to find these cases.
There is no reason to call a getter without observing the result, doing
so indicates an error in the code. Mark these methods as [[nodiscard]]
to find these cases.
There is no reason to call a getter without observing the result, doing
so indicates an error in the code. Mark these methods as [[nodiscard]]
to find these cases.
There is no reason to call a getter without observing the result, doing
so indicates an error in the code. Mark these methods as [[nodiscard]]
to find these cases.
LookupServer can now itself server as a DNS server! To service DNS clients, it
uses the exact same lookup logic as it does for LibIPC clients. Namely, it will
synthesize records for data from /etc/hosts on its own (you can use this to
configure host names for your domain!), and forward other questions to
configured upstream DNS servers. On top of that, it implements its own caching,
so once a DNS resource record has been obtained from an upstream server,
LookupServer will cache it locally for faster future lookups.
The DNS server part of LookupServer is disabled by default, because it requires
you to run it as root (for it to bind to the port 53) and on boot, and we don't
want either by default. If you want to try it, modify SystemServer.ini like so:
[LookupServer]
Socket=/tmp/portal/lookup
SocketPermissions=666
Priority=low
KeepAlive=1
User=root
BootModes=text,graphical
and enable server mode in LookupServer.ini like so:
[DNS]
Nameservers=...
EnableServer=1
If in the future we implement socket takeover for IP sockets, these limitations
may be lifted.
Where it belongs, alongside the /etc/hosts check. The inner lookup() method is
really about talking to a specific DNS server.
Also, don't bail out on a empty name. An empty DNSName is actually '.' — a
single dot — aka the DNS root.
...just like we store m_lookup_cache, in other words.
This immediately lets us match on types: for instance we will now only resolve
1.0.0.127.in-addr.arpa to localhost if asked for type PTR, not for type A. In
the future, this could also let us have the same /etc/hosts name resolve
to *multiple* addresses.