Skip to content

Mixing crates using different panic modes may introduce UB if a non-Rust unwind "escapes" into panic=abort crate via "C-unwind" #96926

Description

@BatmanAoD

This is a case of undefined behavior around unwinding that will not be fixed by the stabilization of the "C-unwind" ABI.

Suppose there exists a C++ library with this function:

void cpp_unwind() {
    throw "gotcha";
}

If this function is compiled as part of a crate with panic=unwind:

extern "C-unwind" {
    cpp_unwind()
}

pub fn unwinds() { unsafe { cpp_unwind() } }

...and then called from a crate compiled with panic=abort, the behavior is undefined, because the calling function will be compiled with the assumption that unwinding is impossible.

Note:

  • If cpp_unwind is declared with extern "C", the behavior will be well-defined: the runtime will abort even if panic=unwind is used.
  • Cargo does not support mixing panic modes like this, so this situation is only possible by invoking rustc directly (or via a different build system).
  • The unwind must originate outside of Rust, because only one panic!() implementation will be linked in the final binary, so using panic=abort will prevent panic!() from unwinding the stack in the first place.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

C-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions