Stream: git-wasmtime

Topic: wasmtime / PR #14303 Fix native stack-walking on macOS arm64


view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:54):

macovedj opened PR #14303 from macovedj:arm64-native-unwind to bytecodealliance:main:

macOS disables pointer authentication for ordinary arm64 executables. This PR checks the main executable’s Mach-O header and enables return-address signing by default only for arm64e processes.

Previously, Cranelift generated unwind metadata that incorrectly described unsigned return addresses as signed. This caused native backtraces captured inside host imports to stop before recovering the Wasm callers.

The issue was discovered while developing native stack-walking tests for a companion PR that uses libunwind’s whole-section registration APIs.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:54):

macovedj requested alexcrichton for a review on PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:54):

macovedj requested wasmtime-compiler-reviewers for a review on PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:54):

macovedj requested wasmtime-core-reviewers for a review on PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:54):

macovedj requested wasmtime-default-reviewers for a review on PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 12:55):

macovedj edited PR #14303:

macOS disables pointer authentication for ordinary arm64 executables. This PR checks the main executable’s Mach-O header and enables return-address signing by default only for arm64e processes.

Previously, Cranelift generated unwind metadata that incorrectly described unsigned return addresses as signed. This caused native backtraces captured inside host imports to stop before recovering the Wasm callers.

The issue was discovered while developing native stack-walking tests in https://github.com/bytecodealliance/wasmtime/pull/14304.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 14:46):

github-actions[bot] added the label wasmtime:api on PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 14:46):

github-actions[bot] added the label cranelift on PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 15:35):

:memo: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 15:35):

:speech_balloon: alexcrichton created PR review comment:

Question on this, as I'm pretty unfamiliar with this part of macos -- Rust has a arm64e-apple-darwin in contrast to the normal aarch64-apple-darwin target. I naively thought that the normal target used pointer authentication everywhere, but I suppose it doesn't and the arm64e target does? Is it possible to use aarch64-apple-darwin libraries within an arm64e executable? If so, then this check seems required, but if not then another option might be to detect when the target arch is arm64e which would probably require a build script (I don't see a #[cfg] in Rust for this)

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 15:35):

:speech_balloon: alexcrichton created PR review comment:

Could these features/requirements be dropped? In theory this is a good test for all platforms to execute.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 15:35):

:speech_balloon: alexcrichton created PR review comment:

Could this test use the backtrace crate directly rather than usnig the unsafe APIs here? That way it should be able to more easily run on other platforms too.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 19:38):

macovedj updated PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 19:41):

:memo: macovedj submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 19:41):

:speech_balloon: macovedj created PR review comment:

I’m also getting familiar with this part of macos. From what I can tell, aarch64-apple-darwin uses the ordinary arm64 ABI. It’s also possible to run arm64e binaries with pointer authentication disabled, and when disabled, these targets can mix through dynamically loaded libraries.

This means my original check isn’t sufficient, since it checks the main executable’s architecture rather than whether authentication is actually enabled, so I replaced it with thread_get_state query that checks the runtime authentication state.

I’m not sure how prevalent these mixed configurations are, although it seems LLVM explicitly documents them, and I was able to reproduce locally. So a build script check for compilation target would definitely miss this case, but if you think that's acceptable then we could still consider it

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 20:09):

:memo: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 20:09):

:speech_balloon: alexcrichton created PR review comment:

It's to not bother with this, most tests in Wasmtime break when features are disabled and we don't try to keep that working. It's assumed the default features are enabled when tests are running

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 20:09):

:speech_balloon: alexcrichton created PR review comment:

It's ok to trim this down to just not(miri), everything else should naturally fall out of the testing matrix

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 20:09):

:speech_balloon: alexcrichton created PR review comment:

Ah I forgot to ask from prior, but could this be moved to the tests/all/*.rs suite?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 09 2026 at 20:09):

:speech_balloon: alexcrichton created PR review comment:

Man every time I think I know how pointer authentication works in the "real world" new things come up and turns out I have no idea what's happening...

I can't exactly claim to know whether what you're adding in this PR is correct myself -- would you be able to link to documentation of these constants and/or the APIs here to learn about whether it's dynamically enabled?

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 15:56):

macovedj updated PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 15:57):

:memo: macovedj submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 15:57):

:speech_balloon: macovedj created PR review comment:

It would be nice if this were documented more clearly. I had to look through XNU, which was relatively gnarly, and I've done my best to concisely and clearly explain what is going on below.

For this plugin-host compatibility rule, the kernel checks whether the executable is an Apple platform binary, along with checking for certain entitlements or an exception list. These include the documented Disable Library Validation entitlement.

For qualifying arm64e hosts, the kernel disables user JOP protection (further reading on JOP available here). The comment explicitly says this accommodates arm64 plugins. This means the main executable’s arm64e architecture alone doesn’t establish whether pointer authentication is enabled.

When exporting thread state, the kernel sets NO_PTRAUTH if user JOP is disabled for the calling or target thread. This is the info we are querying with thread_get_state (see bindings here). We query our own thread, so the calling and target thread are the same.

One of the more confusing details is the field name: the kernel calls it flags, while the userspace definitions call that same 32-bit field either __opaque_flags or __pad. The mach2 binding uses the __pad spelling and #[repr(C)] layout, so that is where we read the flag. There is no separate copy from flags into __pad; they describe the same bytes.

The NO_PTRAUTH constant is 0x1, so state.__pad & 0x1 == 0 checks that this “authentication disabled” bit is clear.

Please let me know if there’s any other information or testing I can provide to help build confidence in these changes.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 16:09):

:thumbs_up: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 16:09):

alexcrichton added PR #14303 Fix native stack-walking on macOS arm64 to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 16:35):

github-merge-queue[bot] removed PR #14303 Fix native stack-walking on macOS arm64 from the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 16:46):

macovedj commented on PR #14303:

Ah looking at the CI failure I think I should skip Pulley in my tests

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 16:47):

macovedj updated PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 16:50):

alexcrichton has enabled auto merge for PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 16:56):

alexcrichton added PR #14303 Fix native stack-walking on macOS arm64 to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 17:23):

:check: alexcrichton merged PR #14303.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 14 2026 at 17:23):

alexcrichton removed PR #14303 Fix native stack-walking on macOS arm64 from the merge queue.


Last updated: Sep 20 2026 at 18:08 UTC