leomccormack/SPARTA

Powermap, DirASS, and SLDoA plugins will crash on MacOS if a camera is selected while hosting the plugins on a "Runtime Hardened" DAW

leomccormack opened this issue · 2 comments

I don't see a way around this. If REAPER (or any other run-time hardened DAW) doesn't present the user with the option to enable it to have "Camera" access, then this crash is inevitable:

2024-01-30 14:17:49.282736+0200 REAPER[2004:35811] [access] This app has crashed because it has a hardened runtime and attempted to access privacy-sensitive data without an entitlement indicating its intent to access this data. The app must have the 'com.apple.security.device.camera' entitlement.

However, since an acoustic camera (see: for example) is quite a niche use case for an audio plugin, I think it would be unlikely that the REAPER devs would present this request to their users.

In previous versions of MacOS, the user could force/manually add permissions for an app to use the camera. However, as of 11.0+ it seems like this is no longer the case.

Therefore, unless REAPER decides to request Camera access for these niche use cases, or Apple allows its users to decide these things for themselves, or we remove this feature from the plugins, then this crash is unavoidable.

Unless someone has any other ideas?

(Note that the crash log looks something like this):

-------------------------------------
Translated Report (Full Report Below)
-------------------------------------

Process:               REAPER [32117]
Path:                  /Applications/REAPER.app/Contents/MacOS/REAPER
Identifier:            com.cockos.reaper
Version:               7.5.0_32b987cu (7.5.0_32b987cu)
Code Type:             ARM-64 (Native)
Parent Process:        launchd [1]
User ID:               1104018618

Date/Time:             2024-01-30 12:34:05.6150 +0200
OS Version:            macOS 13.6.3 (22G436)
Report Version:        12
Anonymous UUID:        CE9EC1E3-2CA3-0757-C7ED-202482DA80E5

Sleep/Wake UUID:       1453D8A8-FF6D-4C5E-A75F-06328571F2BF

Time Awake Since Boot: 830000 seconds
Time Since Wake:       2583 seconds

System Integrity Protection: enabled

Crashed Thread:        2  Dispatch queue: com.apple.root.default-qos

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000

Termination Reason:    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 com.apple.security.device.camera key with a string value explaining to the user how the app uses this data.

Thread 0:: reaper Dispatch queue: com.apple.main-thread
0   CoreFoundation                	       0x18daf5304 __CFStringHash + 976
1   CoreFoundation                	       0x18db0c270 -[__NSDictionaryM objectForKey:] + 108
2   CoreMedia                     	       0x19710ca34 figRegistryItemCreate + 344
3   CoreMedia                     	       0x19710c7a0 registryCacheProcessBundle + 300
4   CoreFoundation                	       0x18db2daac CFArrayApplyFunction + 72
5   CoreMedia                     	       0x19710bb04 registryCacheAddPath + 244
6   CoreFoundation                	       0x18db33a88 __CFSetApplyFunction_block_invoke + 28
7   CoreFoundation                	       0x18db338a0 CFBasicHashApply + 148
8   CoreFoundation                	       0x18db337e4 CFSetApplyFunction + 320
9   CoreMedia                     	       0x19710ce4c FigRegistryRescan + 56
10  CoreMediaIO                   	       0x19d17f3b8 CMIOUnitCreateFromDescription + 176
11  CoreMediaIO                   	       0x19d153030 CMIOUnitNodeInfo::Open() + 76
12  CoreMediaIO                   	       0x19d141ff4 CMIOGraph::CreateNode(unsigned int, unsigned int, OpaqueCMIOUnit*, CMIOUnitDescription const&, void const*, int&) + 236
13  CoreMediaIO                   	       0x19d141dc8 CMIOGraphCreateNode + 388
14  AVFCapture                    	       0x1a95b59a8 -[AVCaptureSession_Tundra _buildSupportUnitsForVideoInputPort:error:] + 1232
15  AVFCapture                    	       0x1a95b4ff4 -[AVCaptureSession_Tundra _buildGraphUnitsForInputPort:error:] + 584
16  AVFCapture                    	       0x1a95b32e8 -[AVCaptureSession_Tundra _buildAndRunGraph] + 648
17  AVFCapture                    	       0x1a95b46e4 -[AVCaptureSession_Tundra _setRunning:] + 332
18  AVFCapture                    	       0x1a95b4244 -[AVCaptureSession_Tundra startRunning] + 168
19  sparta_powermap               	       0x164ca265c juce::CameraDevice::createViewerComponent() + 88
20  sparta_powermap               	       0x164b27dd0 PluginEditor::cameraChanged() + 1000
21  sparta_powermap               	       0x164b2530c PluginEditor::comboBoxChanged(juce::ComboBox*) + 136
22  sparta_powermap               	       0x164bd8564 juce::ComboBox::handleAsyncUpdate() + 148
23  sparta_powermap               	       0x164c6fd2c juce::MessageQueue::runLoopSourceCallback(void*) + 332
24  CoreFoundation                	       0x18db6a5ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
25  CoreFoundation                	       0x18db6a540 __CFRunLoopDoSource0 + 176
26  CoreFoundation                	       0x18db6a2b0 __CFRunLoopDoSources0 + 244
27  CoreFoundation                	       0x18db68eb8 __CFRunLoopRun + 828
28  CoreFoundation                	       0x18db68428 CFRunLoopRunSpecific + 612
29  HIToolbox                     	       0x1973bcdf0 RunCurrentEventLoopInMode + 292
30  HIToolbox                     	       0x1973bcc2c ReceiveNextEventCommon + 648
31  HIToolbox                     	       0x1973bc984 _BlockUntilNextEventMatchingListInModeWithFilter + 76
32  AppKit                        	       0x190d90908 _DPSNextEvent + 636
33  AppKit                        	       0x190d8faa4 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 716
34  AppKit                        	       0x190d83f08 -[NSApplication run] + 464
35  AppKit                        	       0x190d5b358 NSApplicationMain + 880
36  dyld                          	       0x18d733f28 start + 2236

Thread 1:
0   libsystem_pthread.dylib       	       0x18da86d8c start_wqthread + 0

Thread 2 Crashed::  Dispatch queue: com.apple.root.default-qos
0   libsystem_kernel.dylib        	       0x18da58d6c __abort_with_payload + 8
1   libsystem_kernel.dylib        	       0x18da7de40 abort_with_payload_wrapper_internal + 104
2   libsystem_kernel.dylib        	       0x18da7de74 abort_with_payload + 16
3   TCC                           	       0x19275e7f0 __TCC_CRASHING_DUE_TO_PRIVACY_VIOLATION__ + 172
4   TCC                           	       0x19275f108 __TCCAccessRequest_block_invoke.203 + 588
5   TCC                           	       0x19275c5ac __tccd_send_message_block_invoke + 632
6   libxpc.dylib                  	       0x18d7d1650 _xpc_connection_reply_callout + 124
7   libxpc.dylib                  	       0x18d7d1540 _xpc_connection_call_reply_async + 88
8   libdispatch.dylib             	       0x18d8dc480 _dispatch_client_callout3 + 20
9   libdispatch.dylib             	       0x18d8fa624 _dispatch_mach_msg_async_reply_invoke + 344
10  libdispatch.dylib             	       0x18d8eec04 _dispatch_kevent_worker_thread + 1280
11  libsystem_pthread.dylib       	       0x18da880ac _pthread_wqthread + 344
12  libsystem_pthread.dylib       	       0x18da86d94 start_wqthread + 8

Actually, that can be circumvented if Reaper is added manually into the "Transparency, Consent, and Control" (TCC) configuration of MacOS.
Tested and working with live camera 360 feed from a Ricoh Theta V, using the SPARTA powermac VST, on an Intel MacBook Pro 2015 with Catalina, and a M1 MacBook Pro 2021 with Ventura.

Instructions for Big Sur+ (check the bottom for info on older systems):

  • Give System Settings/Privacy & Security/Full Disk Access to Terminal, if not enabled
  • In Terminal, backup the permissions database file, and open the database with sqlite

cp ~/Library/Application\ Support/com.apple.TCC/TCC.db ~/Desktop/TCC.db.bak
sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db

  • In Sqlite, modify the access values manually for Reaper and camera (for microphone access, replace service with 'kTCCServiceMicrophone’):

insert into access
values
('kTCCServiceCamera','com.cockos.reaper', 0, 2, 3, 1, null, null, null, 'UNUSED', null, 0, 1669648527);
.quit

This is the table "access" schema:

(service TEXT NOT NULL,
client TEXT NOT NULL,
client_type INTEGER NOT NULL,
auth_value INTEGER NOT NULL,
auth_reason INTEGER NOT NULL,
auth_version INTEGER NOT NULL,
csreq BLOB,
policy_id INTEGER,
indirect_object_identifier_type INTEGER,
indirect_object_identifier TEXT NOT NULL DEFAULT 'UNUSED',
indirect_object_code_identity BLOB,
flags INTEGER,
last_modified INTEGER NOT NULL DEFAULT (CAST(strftime('%s','now') AS INTEGER))

For older macOS, some of the columns are removed or renamed, check here for detailed info!
https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive