Skip to content
This repository was archived by the owner on Oct 22, 2026. It is now read-only.
This repository was archived by the owner on Oct 22, 2026. It is now read-only.

Undefined behavior: the library panics across FFI boundary #354

Open

Description

@Kixunil

Panicking across FFI boundary is UB but the library does it anyway in rustsecp256k1_v0_4_1_default_illegal_callback_fn. This has to be changed to abort. (infinite loop in non-std, I think)

Activity

  1. real-or-random commented on Jan 4, 2022

    @real-or-random
    Collaborator

    See #290 and the first bullet in #288 (comment)

  2. Kixunil commented on Jan 4, 2022

    @Kixunil
    CollaboratorAuthor

    Forgot it's no longer UB. Relying on UB even with test doesn't sound good to me. Once could build the crate with a slightly different compiler or even in non-test mode could cause issues. We literally can't be sure, that's pretty much what "undefined" means.

  3. real-or-random commented on Jan 5, 2022

    @real-or-random
    Collaborator

    Well yeah, it's not ideal for sure but I think we've explored all options in #288 and concluded this is the best. Or what would you suggest? You mentioned abort but it requires std.

  4. Kixunil commented on Jan 5, 2022

    @Kixunil
    CollaboratorAuthor
    #[cfg(feature = "std")]
    {
        std::process::abort();
    }
    #[cfg(not(feature = "std"))]
    {
        loop {}
    }
  5. Kixunil commented on Jan 5, 2022

    @Kixunil
    CollaboratorAuthor

    Another no_std alternative:

    struct PanicOnDrop;
    
    impl Drop for PanicOnDrop {
        fn drop(&mut self) {
            panic!("force abort by double panic");
        }
    }
    
    let bomb = PanicOnDrop;
    panic!("force abort by double panic");

    However not sure how it translates on embedded and similar platforms.

  6. real-or-random commented on Jan 5, 2022

    @real-or-random
    Collaborator

    I believe the double panic is indeed a way to access core::intrinsics::abort, which is otherwise not exposed in no_std. That may be a reasonable alternative I think.

    I'm personally still too lazy to bother with this but feel free to open a PR.

  7. elichai commented on Jan 5, 2022

    @elichai
    Member

    I'm not sure there's anything to fix here.
    right now panicking across FFI boundries is not UB.
    Even when it was compiler devs explicitly allowed it to just pass through to support people doing longjumps, See: https://github.com/rust-lang/project-ffi-unwind/blob/master/periodic-summaries/October-2ndHalf.md#letting-extern-c-unwind and a lot of threads in Zulip about it

  8. apoelstra commented on Jan 5, 2022

    @apoelstra
    Member

    I tend to agree with @elichai.

    I would ACK/accept a PR to use the double-panic bomb, since I think this behavior is still UB on the verison of rustc that mrustc supports (I think), and I appreciate that my "it's not UB on new stuff, and empirically the UB on old stuff has ok behavior" logic is not very sound. But I don't feel strongly enough about this that I would do the work myself.

  9. added a commit that references this issue on Jan 5, 2022
    5deccc1
  10. Kixunil commented on Jan 5, 2022

    @Kixunil
    CollaboratorAuthor

    No problem, submitted the PR.

  11. added 2 commits that reference this issue on Jan 5, 2022
    6ff72f8
    ffac2d6
  12. Kixunil commented on Jan 5, 2022

    @Kixunil
    CollaboratorAuthor

    Actually I just found out that panic across FFI is still UB - it got reverted and as far as I can see it wasn't reintroduced since then.

  13. apoelstra commented on Jan 5, 2022

    @apoelstra
    Member

    Wow!! Good find.

  14. real-or-random commented on Jan 6, 2022

    @real-or-random
    Collaborator

    Oh I just sad in #358 that we should let it go.... But that was before I saw the comment here that the change got reverted. To be honest, I don't know what to do.

  15. Kixunil commented on Jan 6, 2022

    @Kixunil
    CollaboratorAuthor

    I see one, hopefully reasonable, way forward: have static AtomicPtr<fn(&str) -> !> storing the error handler initialized with null and a public function to set it.
    The error handling code will load it and:

    • call it if not null
    • call eprintln!() + abort() on std
    • loop forever in no_std

    This behavior will be documented for no_std and consumers will be encouraged to provide their error handler.

  16. elichai commented on Jan 6, 2022

    @elichai
    Member

    Actually I just found out that panic across FFI is still UB - it got reverted and as far as I can see it wasn't reintroduced since then.

    Wait, it's true that it got reverted, but only until extern "C-unwind" will be implemented, which it got implemented here: rust-lang/rust#76570, I'm pretty sure it is defined as abort right now, but let me try to get some official clarification here: rust-lang/rust#52652 (comment)

  17. apoelstra commented on Jan 6, 2022

    @apoelstra
    Member

    @elichai even if it is defined as of Rust 1.57 (or whatever) I think that's too far in the future (at least two years before that comes under our MSRV, maybe longer because post-Rust-2018 there's are far fewer essential features we're missing), and we need to handle this properly here.

    I like @Kixunil's propasal.

  18. added 4 commits that reference this issue on Jan 7, 2022
    40919c2
    0f351a7
    96ddf07
    4aabbbd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions