Previously, we were breaking up digits into groups without regard for
the locale's minimumGroupingDigits value in the CLDR. This value is 1 in
most locales, but is 2 in locales such as pl-PL. What this means is that
in those locales, the group separator should only be inserted if the
thousands group has at least 2 digits. So 1000 is formatted as "1,000"
in en-US, but "1000" in pl-PL. And 10000 is "10,000" in en-US and
"10 000" in pl-PL.
For example, say you try to create a Value from an Array and forgot to
include LibJS/Runtime/Array.h. This would cause the boolean constructor
to be used instead of a compile error.
We were marking the execing thread as Runnable near the end of
Process::do_exec().
This was necessary for exec in processes that had never been scheduled
yet, which is a specific edge case that only applies to the very first
userspace process (normally SystemServer). At this point, such threads
are in the Invalid state.
In the common case (normal userspace-initiated exec), making the current
thread Runnable meant that we switched away from its current state:
Running. As the thread is indeed running, that's a bogus change!
This created a short time window in which the thread state was bogus,
and any attempt to block the thread would panic the kernel (due to a
bogus thread state in Thread::block() leading to VERIFY_NOT_REACHED().)
Fix this by not touching the thread state in Process::do_exec()
and instead make the first userspace thread Runnable directly after
calling Process::exec() on it in try_create_userspace_process().
It's unfortunate that exec() can be called both on the current thread,
and on a new thread that has never been scheduled. It would be good to
not have the latter edge case, but fixing that will require larger
architectural changes outside the scope of this fix.
This makes sure DeviceManagement::try_create_device will call the
static factory function (if available) instead of directly calling the
constructor, which will allow us to move OOM-fallible calls out of
Device constructors.
If we panic the kernel for a storage-related reason, we might as well be
helpful and print out a list of detected storage devices and their
partitions to help with debugging.
Reasons for such a panic include:
- No boot device with the given name found
- No boot device with the given UUID found
- Failing to open the root filesystem after determining a boot device
Before attempting to remove the device while handling an AHCI port
interrupt, check if m_connected_device is even non-null.
This happened during my bare metal run and caused a kernel panic.
This check isn't needed because download_file() will check if it exists
already before doing the download. Worse, it would prevent the generator
target from being defined if the file existed, which then made CMake not
realize the generated files were important and delete them.
After fixing the CMake file to use the correct paths, users may have had
to manually remove the existing downloaded pnp.ids.html for CMake to re-
run the generator. So this change renames the downloaded file to
pnp_ids.html to ensure everyone picks up that change without manual
intervention.
Code generators that generate their files for both Lagom and Serenity
have a blob in their CMake file like this:
set(TIME_ZONE_DATA_HEADER LibTimeZone/TimeZoneData.h)
set(TIME_ZONE_DATA_IMPLEMENTATION LibTimeZone/TimeZoneData.cpp)
set(TIME_ZONE_META_TARGET_PREFIX LibTimeZone_)
if (CMAKE_CURRENT_BINARY_DIR MATCHES ".*/LibTimeZone")
# Serenity build.
set(TIME_ZONE_DATA_HEADER TimeZoneData.h)
set(TIME_ZONE_DATA_IMPLEMENTATION TimeZoneData.cpp)
set(TIME_ZONE_META_TARGET_PREFIX "")
endif()
LibEDID generates files only for Serenity, but was using the Lagom build
version of the _HEADER, _IMPLEMENTATION, and _PREFIX variables. Thus if
pnp_ids.cmake was ever touched, the following error would be raised:
Userland/Libraries/LibEDID/EDID.cpp:18:18: fatal error:
LibEDID/PnpIDs.h: No such file or directory
18 | # include <LibEDID/LibEDID/PnpIDs.h>
Use the Serenity paths in pnp_ids.cmake and in the #include within
LibEDID itself.
A number of crashes in this `VERIFY_NOT_REACHED` case have been
reported on discord. Lets add some tracing to gather more information
and help diagnose what is the cause of these crashes.
There are many assumptions in the stack that argc is not zero, and
argv[0] points to a valid string. The recent pwnkit exploit on Linux
was able to exploit this assumption in the `pkexec` utility
(a SUID-root binary) to escalate from any user to root.
By convention `execve(..)` should always be called with at least one
valid argument, so lets enforce that semantic to harden the system
against vulnerabilities like pwnkit.
Reference: https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
This allows us to enable Write-Combine on e.g. framebuffers,
significantly improving performance on bare metal.
To keep things simple we right now only use one of up to three bits
(bit 7 in the PTE), which maps to the PA4 entry in the PAT MSR, which
we set to the Write-Combine mode on each CPU at boot time.
InodeWatcher::register_inode was already partially fallible, but the
insertion of the inodes and watch descriptions into their respective
hash maps was not. Note that we cannot simply TRY the insertion into
both, as that could result in an inconsistent state, instead we must
remove the inode from the inode hash map if the insertion into the
watch description hash map failed.