Opened 6 weeks ago
#74272 new defect
emacs-app: subprocesses crash with SIGABRT on TCC-gated frameworks (missing NS*UsageDescription keys)
| Reported by: | diekhans (Mark Diekhans) | Owned by: | |
|---|---|---|---|
| Priority: | Normal | Milestone: | |
| Component: | ports | Version: | |
| Keywords: | haspatch | Cc: | drkp (Dan Ports) |
| Port: | emacs-app |
Description
## Description
Emacs.app as built by the emacs-app subport declares usage-description keys only for the
file-access TCC services and Apple Events:
$ plutil -p /Applications/MacPorts/Emacs.app/Contents/Info.plist | grep UsageDescription "NSAppleEventsUsageDescription" => "Emacs requires permission to send AppleEvents to other applications." "NSDesktopFolderUsageDescription" => "Emacs requires permission to access the Desktop folder." "NSDocumentsFolderUsageDescription" => "Emacs requires permission to access the Documents folder." "NSDownloadsFolderUsageDescription" => "Emacs requires permission to access the Downloads folder." "NSRemovableVolumesUsageDescription" => "Emacs requires permission to access files on Removable Volumes."
None of the class-based services (Photos, Camera, Microphone, Contacts, Calendars, Reminders, Location, Speech Recognition, Bluetooth) are declared.
macOS TCC attributes a privacy check to the responsible process found by walking up the parent
chain. For a command-line program started from a shell hosted inside Emacs (M-x shell, eshell,
vterm, M-x compile, org-babel, …) that responsible process is Emacs.app. So such a program is
killed with SIGABRT instead of getting the normal permission dialog — even if its own bundle
declares the required key.
### Reproduction
Build a bundle-less probe that only touches Photos.framework (full source in the linked PR):
clang -framework Photos -framework Foundation -o photo_probe photo_probe.m
Run it from a shell inside Emacs. Crash report:
procName => photo_probe
parentProc => bash
responsibleProc => Emacs
coalitionName => org.gnu.Emacs
exception => EXC_CRASH / SIGABRT (shell reports exit 134)
termination => namespace TCC, code 0:
"This app has crashed because it attempted to access privacy-sensitive data without a
usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription
key with a string value explaining to the user how the app uses this data."
Run from iTerm2 directly: works as expected.
This was originally hit running osxphotos/PyObjC scripts from a shell inside Emacs, but it is not
Python-specific.
### Environment
- macOS 26.5.2 (25F84), Mac16,11 (Apple M4 Pro)
emacs-app @30.2_14+nativecomp+rsvg+treesitter- GNU Emacs 30.2 (build 2, aarch64-apple-darwin25.5.0, NS appkit-2685.60)
### Notes
Terminal.app is not a counterexample — it declares zero usage descriptions and relies on the
Apple-private entitlement com.apple.private.tcc.allow-prompting = [kTCCServiceAll], which
third-party apps cannot use. iTerm2 3.6.8 is the applicable precedent: it declares 14 such keys.
Declaring a usage description does not grant access; it only allows macOS to prompt instead of aborting.
### Fix
Pull request extends the existing files/patch-Info.plist.in.diff with 14 missing class-based keys,
skipping the ones upstream already declares (NSAppleEvents*, the *Folder* and
*RemovableVolumes* keys in both trees, plus NSSpeechRecognition* which emacs master has already
added). Verified to apply with zero fuzz against both the 30.2 tarball and the emacs-master snapshot
used by emacs-app-devel, with no duplicate keys in either.
Also being reported upstream to GNU Emacs, since nextstep/templates/Info.plist.in lives in the
Emacs source tree.
Prepared with the assistance of claude-code.
