Skip to content

fix(install): don't chown -R the shared PrivilegedHelperTools directory - #12

Open
Arpit-Khandelwal wants to merge 1 commit into
XiaoMiku01:mainfrom
Arpit-Khandelwal:fix/install-helper-scoped-chown
Open

Arpit-Khandelwal wants to merge 1 commit into
XiaoMiku01:mainfrom
Arpit-Khandelwal:fix/install-helper-scoped-chown

Conversation

@Arpit-Khandelwal

Copy link
Copy Markdown

Problem

gui/Scripts/install-helper.sh recursively chowns the entire shared /Library/PrivilegedHelperTools directory:

chown -R root:wheel "${TOOLS_DIR}"

That directory is shared by every app's privileged helper. If another app has already installed a macOS‑protected bundle there (e.g. ChromeRemoteDesktopHost.app, whose files carry a com.apple.macl attribute that even root cannot chown), the recursive chown returns Operation not permitted. Because the script runs under set -euo pipefail, it aborts right there — before copying the LaunchDaemon plist and running launchctl bootstrap.

Net effect: the helper binary and dylibs land in place, but the daemon is never registered, so the install "finishes" while the helper stays permanently unreachable. Fixes #11.

Fix

Scope the ownership/permission changes to the files TetherKit actually installs — the helper binary and its libtetherkit* / libusb-* dylibs — instead of recursively chowning the whole shared directory. Foreign helpers in the same directory are never touched, so their protection can no longer abort our install.

-chown -R root:wheel "${TOOLS_DIR}"
-chmod 755 "${TOOLS_DIR}"
-chmod 544 "${INSTALL_PATH}"
-find "${TOOLS_DIR}" -maxdepth 1 -name '*.dylib' -type f -exec chmod 444 {} +
+chmod 755 "${TOOLS_DIR}"
+chown -h root:wheel "${INSTALL_PATH}" "${TOOLS_DIR}"/libtetherkit*.dylib
+if compgen -G "${TOOLS_DIR}/libusb-*.dylib" >/dev/null; then
+  chown -h root:wheel "${TOOLS_DIR}"/libusb-*.dylib
+fi
+chmod 544 "${INSTALL_PATH}"
+find "${TOOLS_DIR}" -maxdepth 1 -type f \
+  \( -name 'libtetherkit*.dylib' -o -name 'libusb-*.dylib' \) -exec chmod 444 {} +

Notes:

  • chmod 755 "${TOOLS_DIR}" is kept (non‑recursive) to preserve the launchd requirement that the directory not be group/other‑writable.
  • chown -h so the libtetherkit symlinks are handled as links, consistent with the cp -a copy above.
  • The chmod 444 find is narrowed to our own dylib names so it can't touch a foreign *.dylib.

Testing

Reproduced the failure and verified the fix in isolation (no root required) by placing a user‑immutable (chflags uchg) file inside a decoy bundle in a temp TOOLS_DIR — a faithful stand‑in for a com.apple.macl‑protected foreign helper, since both reject a real ownership change with EPERM:

  • Before: chown -R faults on the decoy → script aborts (exit 1) → plist step never reached.
  • After: scoped chown completes (exit 0) → plist step reached → decoy left untouched.

bash -n passes on the modified script.

install-helper.sh recursively chowns the entire shared
/Library/PrivilegedHelperTools directory. When another app has already
installed a macOS-protected helper bundle there (e.g.
ChromeRemoteDesktopHost.app, which carries a com.apple.macl attribute),
chown returns "Operation not permitted" on those files. Under
`set -euo pipefail` the script aborts right there — before it copies the
LaunchDaemon plist and runs `launchctl bootstrap`. The helper binary and
dylibs land on disk, but the daemon is never registered, so the install
appears to finish while the helper stays permanently unreachable.

Only chown/chmod the files this tool actually installs (the helper
binary and its libtetherkit/libusb dylibs) instead of the entire shared
directory. Other apps' helpers in the same directory are left untouched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

install-helper.sh aborts and never registers the LaunchDaemon when another app's protected helper exists in /Library/PrivilegedHelperTools

1 participant