Skip to content

Statically linked runtime #877

Description

@agowa

AppImages should run on all Linux Platforms, but currently they don't, this is because it is dynamically linked against glibc.
I tried to run a AppImage on Alpine Linux and it failed because Alpine Linux is build around musl libc instead.
I think AppImages should generally include all necessary dependencies and not some of them. Also adding libc would not increase the resulting size much, depending on the used libc, it may only be from 185k to 8M libc Comparison Chart. And if the binary is also stripped it can also be a much less.

AppImage should do something like this:

  1. When creating, check the required symbols of the application and determine the smallest fitting libc to include.
  2. Always produce statically linked binaries, that don't depend on anything on the system.
  3. Recommend using musl libc instead of glibc, for various reasons like License (MIT ./. LGPL), binary size (527k ./. 8M).

Activity

  1. probonopd commented on Oct 27, 2018

    @probonopd
  2. azubieta commented on Oct 27, 2018

    @azubieta
  3. TheAssassin commented on Oct 28, 2018

    @TheAssassin
  4. TheAssassin commented on Dec 10, 2019

    @TheAssassin
  5. TheAssassin commented on Dec 10, 2019

    @TheAssassin
  6. TheAssassin commented on Dec 10, 2019

    @TheAssassin
  7. changed the title [-]Statically Link binaries[/-] [+]Statically linked runtime[/+] on Dec 10, 2019
  8. added this to the type-3 milestone on Dec 10, 2019
  9. probonopd commented on Dec 11, 2019

    @probonopd
    Member

    Good feature. Since AppImage has no plan to support it

    Actually we are very interested in supporting this, as it would allow us to close #1015 - correct? Let's collaborate 👍

  10. probonopd commented on Dec 11, 2019

    @probonopd
    Member

    The next AppImage type should fix this issue.

    Shall we state "get rid of FUSE" as a goal?

  11. probonopd commented on Dec 11, 2019

    @probonopd
    Member

    can't run without glibc such as Alpine

    Do you think we can change it just so much that it can at least work on Alpine when libc6-compat is installed there? Then it would not even have to be fully static. See #1015

  12. agowa commented on Dec 12, 2019

    @agowa
    Author

    A completely static linked app would also allow to create docker images without userland. E.g. Only the static linked app without any linux userland surrounding it...

    That's not only smaller, but also decreases the attack surface.

  13. probonopd commented on Dec 18, 2019

    @probonopd
    Member

    @TheAssassin would that be something that you think would be doable if we would rewrite the runtime in, say, Rust? Wouldn't the runtime be rather large then because it would have to statically link libfuse? (How large would it become?)

    Or should we try to get rid of FUSE altogether for the future type 3 AppImages?

  14. TheAssassin commented on Dec 18, 2019

    @TheAssassin
    Member

    @TheAssassin would that be something that you think would be doable if we would rewrite the runtime in, say, Rust? Wouldn't the runtime be rather large then because it would have to statically link libfuse? (How large would it become?)

    Or should we try to get rid of FUSE altogether for the future type 3 AppImages?

    You don't need the entire libfuse, you just need a few bits. I've read a bit into fuse-rs, it doesn't seem that complex to me.

    The size is secondary; we can save bloat elsewhere (e.g., by using musl libc properly thinned down to the essential bits, etc.).

    Getting rid of FUSE would be awesome, but I have doubts it's all that easy.

  15. probonopd commented on Dec 18, 2019

    @probonopd
    Member

    Is there any limitation in runtime size?

    No. No hard limitation. (We should try to make it as small and efficient as possible.)

    -----------------------
    static linked loader (ELF)
    -----------------------
    squashfs image
    -----------------------
    

    should be sufficient since we can calculate the length of an ELF (and we are already doing it).

  16. 121 remaining items

  17. s09bQ5 commented on Apr 15, 2024

    @s09bQ5

    @xplshn what you talk about sounds very off-topic. This issue is about the application that provides the filesystem for the real application inside the AppImage. The dependencies of the application inside the AppImage are beyond its scope.

    There is no increased attack surface due to dynamic linking. If you can run code to change LD_LIBRARAY_PATH, you don't need to use this to persuade another application to run your malicious code. You can run your malicious code directly. When application gain privileges through setuid LD_LIBRARY_PATH is ignored.

    Glibc is the prime example of backward compatibility. It has stuck to the same soname for the past 27 years and provides multiple versions of a symbol to support applications that need the old behavior of a function.

    Your points about load time and invisible size might also be false. If an application loads libpipewire from outside the AppImage, there is most likely already another application (e.g. pipewire itself) that has this library loaded and the Linux kernel will share pages between these application as long as they remain unchanged. The dynamic loader just has to resolve the symbols, which is usually done lazily.

  18. xplshn commented on Apr 15, 2024

    @xplshn

    Glibc is the prime example of backward compatibility. It has stuck to the same soname for the past 27 years and provides multiple versions of a symbol to support applications that need the old behavior of a function.

    Try running something compiled in Ubuntu 10.4 in Ubuntu 22...

    I cited that webpage because it'd be bad seen if I pasted here a 100 lines long explanation and demonstration of the pitfalls of dynamic linking. If you are interested in learning, read this.

  19. xplshn commented on Apr 15, 2024

    @xplshn

    You could also read this very informative paper: http://www.nth-dimension.org.uk/pub/BTL.pdf - Title: "Breaking the links: Exploiting the linker"

  20. s09bQ5 commented on Apr 15, 2024

    @s09bQ5

    Try running something compiled in Ubuntu 10.4 in Ubuntu 22...

    Tried hdparm, works.

    I cited that webpage because it'd be bad seen if I pasted here a 100 lines long explanation and demonstration of the pitfalls of dynamic linking. If you are interested in learning, read this.

    Learning from that page? That's just a collection of anecdotes from ancient UNIX systems.

    You could also read this very informative paper: http://www.nth-dimension.org.uk/pub/BTL.pdf - Title: "Breaking the links: Exploiting the linker"

    How do the quirks described in there affect AppImages? The only takeaway I see is that when setting LD_LIBRARY_PATH in an AppImage, one should add : only if the variable is not empty.

    https://catonmat.net/ldd-arbitrary-code-execution

    This is an attack on people trying to analyze a binary with ldd, not on people who intend to run the binary.

  21. xplshn commented on Apr 15, 2024

    @xplshn

    How it relates to AppImages? Binaries compiled statically are portable when packaged as an AppImage, dynamically linked ones are not, and not only are they not, their pitfalls outweigh the benefits.

  22. Korne127 commented on Dec 27, 2024

    @Korne127

    Hey @probonopd,

    I read through this entire issue and its predecessor (#1120) to understand the current situation for the documentation rewrite, and it seems to me that the current state is kind of conflicted:

    You originally wanted to make it the official runtime in April of 2023. However, that didn't happen due to a veto by @TheAssassin for several reasons:

    However, simultaneously, the https://github.com/AppImage/AppImageKit releases now officially state that the new runtime is the correct / standard one and the old one is just kept around for legacy reasons. But this isn't written anywhere else, not even in the README.
    So this creates some confusion, because it's unclear which repository is now the "official" reference implementation. And this issue is still open, which indicates it's still the old one.

    And on the other hand, many people switched to go-appimagetool, simply because of the new runtime, while other AppImage creation tools like linuxdeploy still use the old one.
    And with the unclear status and no visible development in months (if not years), it feels like those might never be updated.


    I think it's really important to get a general update and roadmap:

    • Which one is the official runtime? When will the new one be it?
    • Has anything happened behind the scenes in the last month?
    • Are there concrete plans to change the specification for AppImageLauncher to be compatible again?
    • Are there any other issues preventing the adaption?

    This issue has definitely been driving some people away from AppImage (see musescore/MuseScore#19722); therefore I really think we should try to finally resolve it as soon as possible.

  23. probonopd commented on Dec 27, 2024

    @probonopd
    Member

    Thanks @Korne127. You did very careful research indeed, thank you.
    The official runtime is now https://github.com/AppImage/type2-runtime, which is used by https://github.com/AppImage/appimagetool.

    I am changing the default branch in https://github.com/AppImage/AppImageKit/ to reflect the change. Please let me know if there is still something unclear. Our intent is to modernize things with minimal interruptions to existing workflows.

    tl;dr: Use https://github.com/AppImage/appimagetool from now on, or get your higher-level tools to use it.

    Thank you very much.

  24. Samueru-sama commented on Dec 27, 2024

    @Samueru-sama

    Worth adding that go-appimage is a higher level tool that uses the static runtime by default.

  25. Korne127 commented on Dec 28, 2024

    @Korne127

    @probonopd Thank you very much for this quick answer and explanation.

    So if I understood correctly, https://github.com/AppImage/AppImageKit is now only a plain description while the actual reference implementation has been moved to https://github.com/AppImage/type2-runtime and https://github.com/AppImage/appimagetool. (I can make a PR when I finished the documentation reflecting that change if you're okay with that.)

    Then this issue can be closed, as it has been officially resolved, right? And we'll see when / whether other tools like linuxdeploy will be updated accordingly.

    I still have one question though: As you've talked about changing the specification for the new runtime, will this be done (in near future or at all)? Or will you just continue with the current specification (if it's still applicable)?

  26. probonopd commented on Dec 29, 2024

    @probonopd
    Member

    So if I understood correctly, https://github.com/AppImage/AppImageKit is now only a plain description while the actual reference implementation has been moved to https://github.com/AppImage/type2-runtime and https://github.com/AppImage/appimagetool.

    Correct.

    I still have one question though: As you've talked about changing the specification for the new runtime, will this be done (in near future or at all)? Or will you just continue with the current specification (if it's still applicable)?

    We are hesitant about changing the specs too often and are trying to avoid especially breaking changes too often. So currently we want to max out and then officially release the type 2 spec. Eventually in the (far) future there may be a type 3 spec, but only of there is no other way to do things properly.

    I can make a PR when I finished the documentation

    If you want to do do serious work on the documentation, please discuss with @TheAssassin and myself beforehand in https://github.com/AppImage/docs.appimage.org/issues, as I'd like to switch to a Markdown based workflow (possibly using similar tooling as https://docs.appimage.org/).

    Then this issue can be closed, as it has been officially resolved, right?

    You are correct. Thanks everyone for your patience!

  27. deleted a comment from 09187673035 on Aug 8, 2026
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

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions