This is awesome! Really great write-up, and solid work by Jessie :^)
The Ladybird codebase is generally very defensive, but like every browser, our JavaScript engine is slightly less so (in the pursuit of performance.)
There are architectural lessons to learn here beyond just fixing the bugs found. We've since replaced these allocations (+ related ones) with callee-specific stack memory instead of trying to be clever with heap allocation reuse.
We're also migrating more and more of our memory management to garbage collection, which sidesteps a lot of the traditional C++ memory issues.
As others have mentioned, sandboxing & site isolation will make renderer exploitation a lot less powerful than what's demonstrated here. Even so, we obviously want to avoid it as much as possible!
This particular memory vulnerability, as I understand it, was a result of a `ReadonlySpan<>` targeting a resizable vector. A simple technique used by the scpptool-enforced safe subset of C++ to address this situation is to temporarily move the contents of the resizable vector into a non-resizable vector [1] and target the span at the non-resizable vector instead.
Upon destruction, the non-resizable vector will automatically return the contents back to the original resizable vector. (It's somewhat analogous to borrowing a slice in Rust.)
While it wouldn't necessarily prevent you from doing the flawed/buggy thing you were trying to do, it would prevent it from resulting in a memory vulnerability.
Whatever happens, large parts of the codebase + dependencies will be C++ (or C) for the foreseeable future.
We're working on integrating with Swift, but despite the team's earnest efforts, Swift/C++ interop is still young and unstable.
On a personal note, I'm increasingly feeling like "C++ with a garbage collector" might actually be a reasonable tool for the task at hand. Watching the development of Fil-C in this space..
What'd be the effect of Swift be on the possibility of a Windows port? I know anything end user friendly is ages away, but I don't live in Apple land, and neither does most of the world. Apple has a monopoly on iOS and huge market share on Mac, and is still at 20% or something.
The core Swift Lang has is being made more independent of Apple, and can be compiled for an increasing number of platforms thanks to the LLVM-based compiler
I'm honestly not at all familiar with browsers but I really do wonder if a custom language wouldn't be a reasonable tradeoff. It's not all that insane as that is a path that has been walked before. For instance FoundationDB has their own syntax to manage their actor system which just transpiles to C++: https://github.com/apple/foundationdb/blob/main/flow/README....
V8 also has torque which I think to some degree also fits into that type of mindset.
Out of curiosity, why not C# at this point? It's pretty hard to marry C++ with a high-performant garbage collector, since underlying language semantics does not allow for e.g. compacting GCs.
“ Ladybird started as a component of the SerenityOS hobby project, which only allows C++. The choice of language was not so much a technical decision, but more one of personal convenience. Andreas was most comfortable with C++ when creating SerenityOS, and now we have almost half a million lines of modern C++ to maintain.
However, now that Ladybird has forked and become its own independent project, all constraints previously imposed by SerenityOS are no longer in effect.
We have evaluated a number of alternatives, and will begin incremental adoption of Swift as a successor language, once Swift version 6 is released.”
I've only used it within XCode so can't say which is to blame, but I did frequently get the message "The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions" which seems to be a problem with the language/compiler/type system, not XCode per se
I agree with this, i've been avoiding xcode as much as possible for my little swift projects, but now I do wonder if that still stands for large codebases, I guess you could try and find some big codebases on swift on gh and see how much it takes to compile
The Ladybird codebase is generally very defensive, but like every browser, our JavaScript engine is slightly less so (in the pursuit of performance.)
There are architectural lessons to learn here beyond just fixing the bugs found. We've since replaced these allocations (+ related ones) with callee-specific stack memory instead of trying to be clever with heap allocation reuse.
We're also migrating more and more of our memory management to garbage collection, which sidesteps a lot of the traditional C++ memory issues.
As others have mentioned, sandboxing & site isolation will make renderer exploitation a lot less powerful than what's demonstrated here. Even so, we obviously want to avoid it as much as possible!