fix(desktop): the AppImage shipped a launcher only its builder could execute - #470
Merged
Conversation
…Redis, ClickHouse, and Apache Druid official documentation
…execute linuxdeploy writes `AppRun.wrapped` into the AppDir as `0770 root:root`, and the released image carried that mode. Measured on 0.13.2: `-rwxrwx--- root/root AppRun.wrapped`, reproduced as uid 1000 over root-owned files as `/AppRun: line 12: /AppRun.wrapped: Permission denied`, and fixed by that one file at 0755. The AppImage runtime hides this from the case everyone tests. A type-2 image mounts its squashfs through FUSE privately to the invoking user, and a private FUSE mount skips the kernel permission check - measured too: the shipped 0.13.2 image mounts and opens its window as uid 1000 exactly as it always did. What breaks is every reader that applies real permission checks: an extracted AppDir owned by another uid, a container running as non-root, and firejail's `--appimage` mount, which is what AppImageHub's review CI runs. There the app never starts, with a bare `Permission denied` and no window to diagnose from. So the build now audits the extracted modes and repacks when the audit fails. The repack reuses the original runtime bytes and the original squashfs parameters rather than calling appimagetool again: the runtime is what decides whether the image mounts on the user's machine at all, and swapping it to fix a file mode would trade this defect for a worse one. Verified end to end on Ubuntu 22.04 - the repacked image mounts and opens its window as uid 1000, and its AppDir also runs when the files are root-owned, which the shipped one does not. The audit is `scripts/check-appimage-perms.mjs` so it is unit tested rather than asserted in bash, and both AppImage builds now install squashfs-tools.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



What was wrong
linuxdeploy writes
AppRun.wrappedinto the AppDir as0770 root:root, and every released AppImage carried that mode. On the released 0.13.2 artifact:Reproduced as a different uid over root-owned files:
and the same tree starts normally after
chmod 0755on that one file.Why nothing noticed
The AppImage runtime hides it from the case everyone tests. A type-2 image mounts its squashfs through FUSE privately to the invoking user, and a private FUSE mount skips the kernel permission check. Measured, not assumed: the shipped 0.13.2 image, mounted and run as uid 1000 in a FUSE-capable Ubuntu 22.04 container, opens its window in 1 s exactly as it always did.
What breaks is every reader that applies real permission checks:
--appimage-extractthen run as someone else)--appimagemount, which is what AppImageHub's review CI uses - it mounts as root and drops to the user, so the mode appliesThat last one is how this surfaced: AppImage/appimage.github.io#3861 failed with exactly the line above, then hung until the workflow's 10 minute timeout because no window ever appeared.
The fix
scripts/build-desktop-appimage.shaudits the extracted modes and, when the audit fails, widens them and repacks the image.The repack reuses the original runtime bytes and the original squashfs parameters instead of calling appimagetool again. The runtime is what decides whether the image mounts on the user's machine at all - appimagetool 13's runtime needs libfuse2, which Ubuntu 24.04 does not ship - so regenerating it to fix a file mode would trade this defect for a worse one. Compression and block size are read back from the bundler's own output rather than hardcoded, so a future appimagetool that changes them does not silently repack differently.
The audit lives in
scripts/check-appimage-perms.mjsso it is unit tested rather than asserted in bash, and it runs twice: once on the bundler's output to decide, once on the repacked image to verify, because a repack that dropped the modes would otherwise pass on the strength of its input.Verification
On Ubuntu 22.04 containers, against the released 0.13.2 artifact and the locally repacked one:
Permission denied, no windowcheck-appimage-perms.mjs0770 AppRun.wrappedappdir-lint.sh/desktop-file-validateLocal gates:
format,lint,typecheck,knip,test(33/33 groups),build.scripts/*.mjsis outside the merged-lcov universe (merge-lcov.mjskeepssrc/only), so the coverage gate is unaffected.This PR's own
Build AppImage (x64)job is the first run of the repack path on the release runner image.