AppImageKit icon indicating copy to clipboard operation
AppImageKit copied to clipboard

runtime: Always use link target for /proc/self/exe

Open s-zeid opened this issue 3 years ago • 7 comments

When running an AppImage under gcompat (e.g. on Alpine Linux), fopen("/proc/self/exe", "rb") opens the dynamic linker (e.g. /lib/ld-musl-x86_64.so.1) instead of the AppImage itself. However, readlink("/proc/self/exe", ...) does give the path to the AppImage as expected, even under gcompat.

This commit fixes this problem by always using the link target for /proc/self/exe in places that read the AppImage instead of the link itself. Without this commit, running an AppImage under gcompat results in the error message "This doesn't look like a squashfs image." from squashfuse. With this commit, AppImages run as expected under gcompat.

In order to make --appimage-help and --appimage-portable-{home,config} work under gcompat, I also move the calculation of the fullpath variable in main() to earlier in the function and change print_help() and portable_option() to use it instead of calculating the fullpath separately. (When $TARGET_APPIMAGE is set, since realpath() is (already) used instead of readlink() in that case, this change could result in a different path being used in help output and when creating the portable home and config directories with the respective command line options, but fullpath is already being used to find existing portable directories when running an AppImage, so this should not affect existing portable installations.) For consistency, I also rename the fullpath variable in main() and the corresponding arguments in print_help() and portable_option() to appimage_fullpath.

Fixes #1015 on Alpine Linux systems with gcompat installed, for AppImages made with this changeset applied.

Tested on Alpine Linux edge x86_64 and postmarketOS (based on Alpine) edge aarch64.

s-zeid avatar Jan 28 '22 04:01 s-zeid

Thanks for pointing this out. I wasn't aware of gcompat, a library which provides glibc-compatible APIs for use on musl libc systems.

Opening readlink("/proc/self/exe", ...) does sound reasonable to me. @TheAssassin wdyt?

probonopd avatar Jan 28 '22 16:01 probonopd

You should open an issue with gcompat, that's clearly a bug there.

TheAssassin avatar Jan 28 '22 20:01 TheAssassin

Agree, if gcompat is meant to be compatible with glibc, then it should behave like it. This being said, is there a downside to doing the readlink/realpath on our end?

probonopd avatar Jan 28 '22 20:01 probonopd

No. But someone should let them know about it.

TheAssassin avatar Jan 28 '22 20:01 TheAssassin

Still to be tested using the build from https://github.com/AppImage/AppImageKit/actions/runs/1780621637

probonopd avatar Feb 05 '22 08:02 probonopd

When running an AppImage under gcompat (e.g. on Alpine Linux), fopen("/proc/self/exe", "rb") opens the dynamic linker (e.g. /lib/ld-musl-x86_64.so.1) instead of the AppImage itself. However, readlink("/proc/self/exe", ...) does give the path to the AppImage as expected, even under gcompat.

This being said, is there a downside to doing the readlink/realpath on our end?

I think this causes race conditions when the binary is renamed between the reading of the link and the opening of the path that was read. fopen() directly doesn't seem to possibly cause since it uses some black magic to not actually read the path but somehow accesses the inode directly or such, at least if I recall correctly. (Basically renaming the program binary after it is launched in just the right moment will cause breakage with this merge request when it wouldn't have before.) I would therefore suggest this has a notable downside and shouldn't be merged.

ell1e avatar Jun 29 '22 22:06 ell1e