fix(build): ship world-readable Linux packages when built with npm run build - #281
Open
miadisabelle wants to merge 1 commit into
Open
miadisabelle wants to merge 1 commit into
miadisabelle wants to merge 1 commit into
Conversation
…n build A package built under a restrictive umask installs an app the desktop user cannot open. Files installed or generated under that umask keep modes without world-read — node_modules as npm installed them, build output, and the directories and files electron-builder creates — and dpkg installs them verbatim. electron-builder adds world-read to files it copies itself, but not to asar-unpacked files, to directories it creates, or to files it generates. Built with `npm run build` under umask 0007, 213 of the .deb's 298 entries have no world-read bit, including: drwxrwx--- /opt/Parallel Code/ -rw-rw---- /opt/Parallel Code/resources/app.asar -rw-rw---- /usr/share/applications/parallel-code.desktop so the install directory cannot be entered and the app is missing from the menu. 199 of the 213 are asar-unpacked files under node_modules, so a build-time umask alone cannot fix them. Two parts, both needed: - An afterPack hook normalises the packed app and the build resources directory: directories 755, files 644, or 755 where the owner could already execute them, so no file becomes executable that its owner could not already execute. A mode that is already right is not rewritten. fpm reads the menu icon from build/ directly, so the hook also changes modes in the checkout's build/; git records only the executable bit, which is kept, so no diff results. - `umask 022` in the build script, for the five entries written after the hook runs: the .desktop entry, the changelog, `resources/package-type`, `resources/apparmor-profile`, and the package root. Measured on the .deb from the same checkout and machine: upstream 213 of 298 without world-read afterPack hook only 5 hook + umask 022 0 hook disabled for build/, icon at 0660 icon ships -rw-rw---- hook + umask 022, icon at 0660 0, icon -rw-r--r-- The set of executable files is identical before and after. The hook clears setuid, setgid and sticky bits; the packed tree has none (chrome-sandbox is packed 0755, and the deb's postinst sets 4755 only on systems without user namespaces). CI builds are unaffected: the published v2.0.0 .deb has 293 entries and none without world-read. knip is told `umask` is a shell builtin rather than an unlisted binary.
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.
A
.debbuilt under a restrictive umask installs an app the desktop user can't open. Files installed or generated under that umask keep modes without world-read — node_modules as npm installed them, build output, and the directories and files electron-builder creates — and dpkg installs them verbatim. electron-builder adds world-read to files it copies itself, but not to asar-unpacked files, directories it creates, or files it generates.Built with
npm run buildunder umask 0007, 213 of the .deb's 298 entries have no world-read bit, including:so the install directory can't be entered and the app is missing from the menu. CI is unaffected — the published v2.0.0
.debhas 293 entries, none without world-read — but a local or shared-machine build is not.Two parts, both needed
199 of the 213 are asar-unpacked files under
node_modules, whose modes npm set at install time, so a build-timeumaskalone can't fix them.build/directly, so the hook also changes modes in the checkout'sbuild/— git records only the executable bit, which is kept, so no diff results.umask 022in thebuildscript, for the five entries written after the hook runs: the.desktopentry, the changelog,resources/package-type,resources/apparmor-profile, and the package root.This is electron-userland/electron-builder#2682, closed as not planned; neither electron-builder nor fpm has an option for file modes (
--deb-use-file-permissionsonly affects owner and group).Measured
Same checkout and machine, inspecting the
.debwithdpkg-deb -c:umask 022build/pass,build/icon.pngat 0660-rw-rw----umask 022,build/icon.pngat 0660-rw-r--r--The set of executable files is identical before and after. The hook clears setuid/setgid/sticky bits; the packed tree has none —
chrome-sandboxis packed 0755 and the deb'spostinstsets 4755 only on systems without user namespaces. It returns early on macOS.This only applies through
npm run build, which every Linux path inrelease.ymlandinstall.shuses; a directnpx electron-builderstill gets the hook but not the umask. knip is toldumaskis a shell builtin.npm run checkandcheck:staticpass.🤖 Generated with Claude Code
https://claude.ai/code/session_01SK5d1Qh4JcJVF39HEkFBxX