Skip to content

[AArch64] When signing return addresses by default, using some Concurrency primitives can cause a crash #80059

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
3405691582 opened this issue Mar 17, 2025 · 1 comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels

Comments

@3405691582
Copy link
Member

3405691582 commented Mar 17, 2025

Description

Using -msign-return-address options (like in #78394 on OpenBSD) and Concurrency primitives like withTaskGroup can cause a PAC trap.

The current understanding is that this is due to the fact that on ELF platforms, swift_task_switch may be called through a PLT stub which modifies the stack pointer, but after swift_task_switch the stack pointer is not equivalently adjusted, causing the stack signing to fault.

Reproduction

@main struct Main {
  static func main() async {
    await withTaskGroup(of: Int.self) { group in print("hello") }
  }
}

Execute with swiftc -parse-as-library -g bad.swift -Xcc -Xclang=-msign-return-address=non-leaf.

Expected behavior

Code executes normally.

Environment

aarch64: swift 6.0.3 prebuilt on Linux, swift HEAD on OpenBSD.

Additional information

I don't believe this is posing a problem on Darwin/aarch64 since I am guessing (though have not verified) that Mach-O doesn't really have a concept of the PLT like on ELF platforms do. Return address signing through -msign-return-address appears to be optional on Linux, but turning it on will also highlights the problem. I suspect the stack pointer is not being restored correctly regardless of signing and thus stack would be "leaked" through repeated swift_task_switch calls through the PLT.

On OpenBSD/aarch64, enforcement of indirect branch targets (including return address signing) is mandatory, unless explicitly opted out by informing the platform linker (with -z nobtcfi). The platform compiler adds the flags -mbranch-target-enforce, -msign-return-address=non-leaf, and -msign-return-address-key=a_key by default. When the latter two options are enabled, the compiler emits paciasp and autiasp instructions for PAC on the stack pointer. When there is a misbranch on OpenBSD, the binary will receive a SIGILL signal and code ILL_BTCFI to indicate a branch target issue. When executing the above code, the ESR indicates a pointer authentication fault.

@3405691582 3405691582 added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Mar 17, 2025
@3405691582
Copy link
Member Author

This is mainly of relevance to the OpenBSD port but is not limited to it.

3405691582 added a commit to 3405691582/swift that referenced this issue Mar 28, 2025
To work-around swiftlang#80059, we need to stop return address signing and
opt-out of BTCFI enforcement via enabling a platform linker option.

We don't want to completely undo the BTCFI work in the rare case that
we later figure out how to properly address the above issue, or allow
users who might want to benefit from BTCFI enforcement and won't use
Concurrency. To do this, condition the existing BTCFI flag enforcement
into a configuration option that defaults off for now.

Because the new swift-driver needs to "know" whether the frontend is
configured to opt-out or not, and since the new driver communicates with
the frontend via the target info JSON to begin with, we add a field
that emits the build flavor to signal the right behavior.
3405691582 added a commit to 3405691582/swift-driver that referenced this issue Mar 28, 2025
On the swift side, we added a new build flavor in swiftlang/swift#xxxxx
to opt-out of BTCFI as a way of working around swiftlang/swift#80059.
We communicate this to swift-driver via the frontend with
FrontendTargetInfo.
3405691582 added a commit to 3405691582/swift-driver that referenced this issue Mar 28, 2025
On the swift side, we added a new build flavor in swiftlang/swift#xxxxx
to opt-out of BTCFI as a way of working around swiftlang/swift#80059.
We communicate this to swift-driver via the frontend with
FrontendTargetInfo.
3405691582 added a commit to 3405691582/swift that referenced this issue Mar 28, 2025
To work-around swiftlang#80059, we need to stop return address signing and
opt-out of BTCFI enforcement via enabling a platform linker option.

We don't want to completely undo the BTCFI work in the rare case that
we later figure out how to properly address the above issue, or allow
users who might want to benefit from BTCFI enforcement and won't use
Concurrency. To do this, condition the existing BTCFI flag enforcement
into a configuration option that defaults off for now.

Because the new swift-driver needs to "know" whether the frontend is
configured to opt-out or not, and since the new driver communicates with
the frontend via the target info JSON to begin with, we add a field
that emits the build flavor to signal the right behavior.
3405691582 added a commit to 3405691582/swift that referenced this issue Mar 29, 2025
To work-around swiftlang#80059, we need to stop return address signing and
opt-out of BTCFI enforcement via enabling a platform linker option.

We don't want to completely undo the BTCFI work in the rare case that
we later figure out how to properly address the above issue, or allow
users who might want to benefit from BTCFI enforcement and won't use
Concurrency. To do this, condition the existing BTCFI flag enforcement
into a configuration option that defaults to off for now.

Because the new swift-driver needs to "know" whether the frontend is
configured to opt-out or not, and since the new driver communicates with
the frontend via the target info JSON to begin with, we add a field
that emits the build flavor to signal the right behavior.
3405691582 added a commit to 3405691582/swift that referenced this issue Mar 29, 2025
To work-around swiftlang#80059, we need to stop return address signing and
opt-out of BTCFI enforcement via enabling a platform linker option.

We don't want to completely undo the BTCFI work in the rare case that
we later figure out how to properly address the above issue, or allow
users who might want to benefit from BTCFI enforcement and won't use
Concurrency. To do this, condition the existing BTCFI flag enforcement
into a configuration option that defaults to off for now.

Because the new swift-driver needs to "know" whether the frontend is
configured to opt-out or not, and since the new driver communicates with
the frontend via the target info JSON to begin with, we add a field
that emits the build flavor to signal the right behavior.
3405691582 added a commit to 3405691582/swift that referenced this issue Mar 29, 2025
To work-around swiftlang#80059, we need to stop return address signing and
opt-out of BTCFI enforcement via enabling a platform linker option.

We don't want to completely undo the BTCFI work in the rare case that
we later figure out how to properly address the above issue, or allow
users who might want to benefit from BTCFI enforcement and won't use
Concurrency. To do this, condition the existing BTCFI flag enforcement
into a configuration option that defaults to off for now.

Because the new swift-driver needs to "know" whether the frontend is
configured to opt-out or not, and since the new driver communicates with
the frontend via the target info JSON to begin with, we add a field
that emits the build flavor to signal the right behavior.
3405691582 added a commit to 3405691582/swift-driver that referenced this issue Mar 29, 2025
On the swift side, we added a new build flavor in swiftlang/swift#80389
to opt-out of BTCFI as a way of working around swiftlang/swift#80059.
We communicate this to swift-driver via the frontend with
FrontendTargetInfo.
3405691582 added a commit to 3405691582/swift-driver that referenced this issue Apr 19, 2025
On the swift side, we added a new build flavor in swiftlang/swift#80389
to opt-out of BTCFI as a way of working around swiftlang/swift#80059.
We communicate this to swift-driver via the frontend with
FrontendTargetInfo.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

1 participant