Skip to content

Comments

LibJS: Fix pointer authentication failure in TypedArray#5116

Merged
ADKaster merged 1 commit intoLadybirdBrowser:masterfrom
BertalanD:ptrauth-compat
Jun 17, 2025
Merged

LibJS: Fix pointer authentication failure in TypedArray#5116
ADKaster merged 1 commit intoLadybirdBrowser:masterfrom
BertalanD:ptrauth-compat

Conversation

@BertalanD
Copy link
Member

TypedArray objects need to know their own constructor objects to allow copying. This was implemented by storing a function pointer to the Intrinsic object's method which returns the constructor object.

The problem is that function pointers aren't polymorphic, we can't legally just cast e.g. a Derived* (*ptr)(void) to Base* (*ptr)(void) (this is why the code needed a bit_cast to even compile). But this wasn't actually a problem in practice because their ABIs were the same. But with pointer authentication (Apple's arm64e ABI) this signature mismatch becomes a hard failure and crashes the process.

Fix this by adding a virtual function that returns the intrinsic constructor (actually, a NativeFunction, as typed arrays constructors don't inherit from the base TypedArray constructor) instead of the function pointer.

With this, test-js passes and Ladybird launches correctly when built (with a lot of vcpkg hacks) for arm64e.

`TypedArray` objects need to know their own constructor objects to allow
copying. This was implemented by storing a function pointer to the
`Intrinsic` object's method which returns the constructor object.

The problem is that function pointers aren't polymorphic, we can't
legally just cast e.g. a `Derived* (*ptr)(void)` to `Base*
(*ptr)(void)` (this is why the code needed a `bit_cast` to even
compile). But this wasn't actually a problem in practice because their
ABIs were the same. But with pointer authentication (Apple's `arm64e`
ABI) this signature mismatch becomes a hard failure and crashes the
process.

Fix this by adding a virtual function that returns the intrinsic
constructor (actually, a `NativeFunction`, as typed arrays constructors
don't inherit from the base `TypedArray` constructor) instead of the
function pointer.

With this, test-js passes and Ladybird launches correctly when built
(with a lot of vcpkg hacks) for arm64e.
@BertalanD BertalanD requested a review from ADKaster June 17, 2025 10:39
@BertalanD
Copy link
Member Author

Public arm64e support is only available with the beta releases of Xcode 26 and macOS Tahoe. vcpkg doesn't support it natively at the moment, so I used this wrapper shell script to add the right build arguments:

#!/opt/homebrew/bin/bash

rewritten_args=()
skip_next=0

args=("$@")
found=0
for ((i = 0; i < $#; i++)); do
  if [[ $skip_next -eq 1 ]]; then
    skip_next=0
    continue
  fi

  arg="${args[i]}"

  if [[ "$arg" == "-arch" && $((i + 1)) -lt $# && "${args[i + 1]}" == "arm64" ]]; then
    rewritten_args+=("-arch" "arm64e")
    skip_next=1
    found=1
  elif [[ "$arg" == --target=arm64-* ]]; then
    new_arg="${arg/--target=arm64-/--target=arm64e-}"
    rewritten_args+=("$new_arg")
    found=1
  elif [[ "$arg" == "-target" && $((i + 1)) -lt $# && "${args[i + 1]}" == arm64-* ]]; then
    new_target="${args[i + 1]/arm64-/arm64e-}"
    rewritten_args+=("-target" "$new_target")
    skip_next=1
    found=1
  else
    rewritten_args+=("$arg")
  fi
done

if [ "$found" -eq 0 ]; then
    rewritten_args+=("-arch" "arm64e")
fi


exec $(xcrun -f clang++) "${rewritten_args[@]}"

We also need the hack to vcpkg's meson integration script for Xcode 26 compat:

--- ./buildtrees/versioning_/versions/vcpkg-tool-meson/f0eaf59cb8c65aaf2fa2c1ea4a5ab75a5c04d727/vcpkg_configure_meson.cmake	2025-06-11 08:28:55
+++ ./packages/vcpkg-tool-meson_arm64-osx-dynamic/share/vcpkg-tool-meson/vcpkg_configure_meson.cmake	2025-06-15 13:31:17
@@ -324,9 +324,9 @@
     vcpkg_cmake_get_vars(cmake_vars_file)
     debug_message("Including cmake vars from: ${cmake_vars_file}")
     include("${cmake_vars_file}")
 
-    vcpkg_list(APPEND arg_OPTIONS --backend ninja --wrap-mode nodownload -Doptimization=plain)
+    vcpkg_list(APPEND arg_OPTIONS --backend ninja --wrap-mode nodownload -Dbuildtype=plain -Db_ndebug=if-release)
 
     z_vcpkg_get_build_and_host_system(MESON_HOST_MACHINE MESON_BUILD_MACHINE IS_CROSS)
 
     if(arg_CONFIG STREQUAL "DEBUG")

@ADKaster
Copy link
Member

Regarding that meson hack, can we not patch meson's sources in vcpkg? Or do they not pull meson from source. If you don't want to, I can take a look. It's already been a week since 1.8.2, so I'm not sure when they intend to release the next bump, and the patch file for mesonbuild/meson#14548 is pretty small.

@ADKaster
Copy link
Member

Can the contents of that build script not be replicated by messing with a vcpkg triplet file? We have our own triplets as it is. Is there a tracking issue for arm64e in vcpkg? Is this a CMake limitation as well? I remember seeing a CMake issue from Evan on the Swift team about how CMake and mixed arm64e/arm64 targets are not friends. Something about wanting to pull the triple information from CMAKE_OSX_DEPLOYMENT_TARGET.

Copy link
Member

@ADKaster ADKaster left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem with the changes themselves.

@BertalanD
Copy link
Member Author

Regarding that meson hack, can we not patch meson's sources in vcpkg? [...] If you don't want to, I can take a look.

I have very limited free time for 2 more weeks, so I'd love if you could get that patch into vcpkg.

re. enabling arm64e in vcpkg, what do you think after our brief convo on the MSVC STL Discord server?

@ADKaster
Copy link
Member

I think that enabling arm64e in vcpkg won't be 'hard' per se, just a bit of busywork. It would definitely be a good idea to use that abi for release/distribution builds. Assuming lldb and the sanitizers can handle it.

@ADKaster ADKaster merged commit edeef94 into LadybirdBrowser:master Jun 17, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants