Skip to content

Mac M1: loading libcrypto in an unsafe way #114

Closed

Description

@theothornhill

When trying to install cl+ssl on a new M1 mac using quicklisp, it hangs and is pushing me into LDB, showing this error:

This is SBCL 2.0.11, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (ql:quickload :cl+ssl)
To load "cl+ssl":
  Load 1 ASDF system:
    cl+ssl
; Loading "cl+ssl"
.WARNING: /usr/local/Cellar/sbcl/2.0.11/libexec/bin/sbcl is loading libcrypto in an unsafe way
fatal error encountered in SBCL pid 55608 pthread 0x101042e00:
SIGABRT received.

Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb> 

From #lisp on freenode, @phoe pointed this out while helping me:

It seems like a solution is to add a specific version of libcrypto.

Activity

  1. avodonosov commented on Jan 25, 2021

    @avodonosov
    Member

    I do not really understand the meaning of the "WARNING: /usr/local/Cellar/sbcl/2.0.11/libexec/bin/sbcl is loading libcrypto in an unsafe way".

    But if the problem is about the version of libressl, user code can load any version instead of the default behaviour.
    See the :CL+SSL-FOREIGN-LIBS-ALREADY-LOADED description in the doc (https://common-lisp.net/project/cl-plus-ssl/)

    Let us know if that helps.

  2. phoe commented on Jan 25, 2021

    @phoe

    I do not really understand the meaning of the "WARNING: /usr/local/Cellar/sbcl/2.0.11/libexec/bin/sbcl is loading libcrypto in an unsafe way".

    Seems like "Clients should not load the unversioned libcrypto dylib as it does not have a stable ABI."

    https://stackoverflow.com/questions/58272830/ has some pointers to use a different SSL library binary.

  3. theothornhill commented on Jan 25, 2021

    @theothornhill
    Author

    By reinstalling Homebrew, sbcl and most importantly openssl making sure that in every step we use rosetta 2 it finally works fine.

    I guess some parts of that stack was using arm architecture. The :CL+SSL-FOREIGN-LIBS-ALREADY-LOADED tip was what finally gave me a wrong architecture stacktrace, so thanks :)

  4. fjl commented on Jan 31, 2021

    @fjl
    Contributor

    It's fixed in my PR.

  5. avodonosov commented on Jan 31, 2021

    @avodonosov
    Member

    @fjl , does the load request for unversioned lib really crashes the process?

    @theothornhill says after fixing his packages everything works for him. So I thought the "unsafe way" message is simply a warning for now, not really breaking the load and crashing the process.

  6. theothornhill commented on Jan 31, 2021

    @theothornhill
    Author

    Yes, it does work for me. However, it seems like a known problem, so I might just be lucky for some reason :)

  7. fjl commented on Jan 31, 2021

    @fjl
    Contributor

    says after fixing his packages everything works for him.

    It will work if cffi finds the library in /usr/local/lib first, or in any of the other non-system locations.

    So I thought the "unsafe way" message is simply a warning for now, not really breaking the load and crashing the process.

    The crash happens when loading "/usr/lib/libcrypto.dylib" because it is a stub whose only purpose is to crash the process. You can find other reports of this, for example:

  8. avodonosov commented on Mar 6, 2021

    @avodonosov
    Member

    Closing this - versioned paths were added in #115

  9. slyrus commented on Oct 9, 2021

    @slyrus
    Contributor

    FWIW, I just got this on a fresh install. Not sure what I'm doing wrong.

  10. avodonosov commented on Oct 10, 2021

    @avodonosov
    Member

    @slyrus , probably none of the versioned paths used at

    ;; System-provided libraries. Must be loaded from files with

    and
    ;; System-provided libraries, with version in the file name.

    are present on your machine.

    Please check what version do you have instead.
    You can can load them with https://common-lisp.net/project/cl-plus-ssl/#define-libssl-path.

    If that works we can add those versions to the default lists.

  11. slyrus commented on Oct 10, 2021

    @slyrus
    Contributor

    Using the latest cl+ssl fixed things. Not sure what's changed between HEAD and what's in quicklisp, but the workaround is good enough for me. Thanks!

  12. ngn999 commented on Nov 2, 2021

    @ngn999

    I encountered the same error on macOS Monterey M1 and my fix was the following:

    (ql:quickload :cl+ssl/config)
    (cl+ssl/config:define-libssl-path "/opt/homebrew/opt/openssl/lib/libssl.dylib")
    (cl+ssl/config:define-libcrypto-path "/opt/homebrew/opt/openssl/lib/libcrypto.dylib")
    (ql:quickload :cl+ssl)
    

    I have the same problem on M1. cl+ssl/config will work, but my project needs deployed to linux.

    And I found this patch will work:

    --- a/src/reload.lisp
    +++ b/src/reload.lisp
    @@ -44,10 +44,10 @@
         ;; so we can just use just "libssl.so".
         ;; More info at https://github.com/cl-plus-ssl/cl-plus-ssl/pull/2.
         (:openbsd "libcrypto.so")
    -    (:darwin (:or "/opt/local/lib/libcrypto.dylib"                ;; MacPorts
    +    (:darwin (:or "/opt/homebrew/opt/openssl/lib/libcrypto.dylib" ;; Homebrew Arm64
    +                  "/opt/local/lib/libcrypto.dylib"                ;; MacPorts
                       "/sw/lib/libcrypto.dylib"                       ;; Fink
                       "/usr/local/opt/openssl/lib/libcrypto.dylib"    ;; Homebrew
    -                  "/opt/homebrew/opt/openssl/lib/libcrypto.dylib" ;; Homebrew Arm64
                       "/usr/local/lib/libcrypto.dylib" ;; personalized install
     
                       ;; System-provided libraries. Must be loaded from files with
    @@ -92,10 +92,10 @@
         ;; (missing TLSv1_[1,2]_XXX methods,
         ;; see https://github.com/cl-plus-ssl/cl-plus-ssl/issues/56)
         ;; so first try to load possible custom installations of libssl
    -    (:darwin (:or "/opt/local/lib/libssl.dylib"                ;; MacPorts
    +    (:darwin (:or "/opt/homebrew/opt/openssl/lib/libssl.dylib" ;; Homebrew Arm64
    +                  "/opt/local/lib/libssl.dylib"                ;; MacPorts
                       "/sw/lib/libssl.dylib"                       ;; Fink
                       "/usr/local/opt/openssl/lib/libssl.dylib"    ;; Homebrew
    -                  "/opt/homebrew/opt/openssl/lib/libssl.dylib" ;; Homebrew Arm64
                       "/usr/local/lib/libssl.dylib" ;; personalized install
     
                       ;; System-provided libraries, with version in the file name.
    

    but I don't know why.

  13. fjl commented on Nov 4, 2021

    @fjl
    Contributor

    Someone needs to dig into the dyld_shared_cache on Monterey and check which libssl versions it supports. I don't have Monterey yet, so can't check.

  14. 19 remaining items

  15. theothornhill commented on Nov 19, 2021

    @theothornhill
    Author

    @theothornhill , could you add (format t "%load-foreign-library ~A" path) at https://github.com/cffi/cffi/blob/eac416d11bb483c33c277d164b4c6daccd9af452/src/cffi-scl.lisp#L307 and reproduce the crash?

    I cannot seem to get cffi to print that line, since it seems to crash before we get there.

    An even easier test is to run:

    sbcl --non-interactive --no-userinit --eval '(load-shared-object "/opt/local/lib/libcrypto.dylib")'
    

    This reproduces for me too.

  16. avodonosov commented on Nov 21, 2021

    @avodonosov
    Member

    @theothornhill , strange that you can't get the line printed. Maybe remove .fasl files and rebuild (that's an unlined function). On Linux .fals files can be removed by rm -rf ~/.cache/common-lisp/, probably on MacOS it's the same.

  17. daewok commented on Nov 22, 2021

    @daewok
    Contributor
  18. theothornhill commented on Nov 22, 2021

    @theothornhill
    Author

    Thanks, I wondered if that could be the case. I'll check tonight :)

  19. theothornhill commented on Nov 23, 2021

    @theothornhill
    Author

    @avodonosov @daewok I'm sorry, but I cannot get it to work... I've tried to quickload cffi before quickloading cl+ssl, and also with manually recompiling that function, and the functions it is referenced from, since it's an inlined function.

    What am I missing?

  20. avodonosov commented on Nov 23, 2021

    @avodonosov
    Member

    Difficwlt to say what is missing...

  21. aniketnarvekar commented on Nov 24, 2021

    @aniketnarvekar

    @theothornhill @avodonosov I think the wrong line to edit was mentioned. It should be https://github.com/cffi/cffi/blob/eac416d11bb483c33c277d164b4c6daccd9af452/src/cffi-sbcl.lisp#L366 (cffi-sbcl.lisp instead of cffi-scl.lisp)

    Using your reference I found out that 'try-foreign-library-alternatives' function in libraries.lisp is loading each library from the library-list parameter without checking if its present at specified location. Here is my solution. For me this fixes the sbcl crashes while loading libcrypto library.

  22. daewok commented on Nov 24, 2021

    @daewok
    Contributor

    @theothornhill Maybe you can (trace sb-alien:load-shared-object) instead.

    @aniketnarvekar That is not a good solution. It looks like your patch is at cffi/cffi#193 (it was mentioned in an earlier comment, not sure why it was deleted).

    First, it will not work when loading a system library. You typically do not provide the full path to those, so the probe-file will return NIL except in the unlikely event that *default-pathname-defaults* is bound to the directory containing the library.

    Second, Apple has decided to remove ~all system libraries from the file system and store them in a cache elsewhere. So probe-file will never return non-NIL for those. Apple says the correct way to test for library existence is to dlopen them and check for an error. That makes this bug extra rich since it seems that dlopen("/some/non-existent/path/libcrypto.dylib") causes the process to abort instead of returning an error.

  23. avodonosov commented on Nov 27, 2021

    @avodonosov
    Member

    Anyone sees a problem if I remove all non-standard paths for Darwin - leaving only /usr/lib/libssl.NN.dylib ?

  24. daewok commented on Nov 29, 2021

    @daewok
    Contributor

    Anyone sees a problem if I remove all non-standard paths for Darwin - leaving only /usr/lib/libssl.NN.dylib ?

    Seems reasonable, especially since cl+ssl/config was introduced.

  25. jaemk commented on Dec 7, 2021

    @jaemk

    Others above already mentioned that moving files to /usr/local/lib fixed it, but here's some explicit steps for anyone else struggling with this on osx (I hit this after updating to Monterey),

    In total:

    brew install openssl
    ln -s /usr/local/opt/openssl\@3/lib/libcrypto.dylib /usr/local/lib/libcrypto.dylib
    ln -s /usr/local/opt/openssl\@3/lib/libssl.dylib /usr/local/lib/libssl.dylib
    
  26. avodonosov commented on Dec 9, 2021

    @avodonosov
    Member

    @aniketnarvekar, thank you for confirming a non-existing path crashes the app. I was actually curious to know exactly what path it is - is it one of the path specified in reload.lisp or cffi also falls-back to some default path which causes the crash (reading the cffi code I think it should not, but was curious to be sure).

    As for checking the path presence, while @daewok is right that a generic cffi patch is not good for that, we can do that for our specific paths on cl+ssl level. In the commit referenced above I implemented that.

    So now we try custom paths only if they are present. I hesitated to remove them altogether - do not want to cause inconvenience for people who may depend on them.

    For the record, the custom paths where added in #56.

    I'd appreciate if someone tested the last version and confirmed it works on macOS where it previously crashed.

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