Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MacOS: Catalina: Application crashes if it does not have "Input monitoring" permission #795

Closed
el-dee opened this issue Nov 28, 2019 · 12 comments
Labels
Milestone

Comments

@el-dee
Copy link
Contributor

@el-dee el-dee commented Nov 28, 2019

On MacOS Catalina, a Panda application launched from a terminal crashes if it does not have "Input monitoring" permission.

The backtrace of the log is :

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   com.apple.CoreFoundation      	0x00007fff2db45dd4 CFArrayGetCount + 6
1   libpanda.1.10.dylib           	0x000000010e02ecc9 IOKitInputDevice::IOKitInputDevice(__IOHIDDevice*) + 1049
2   libpanda.1.10.dylib           	0x000000010e030c4a IOKitInputDeviceManager::on_match_device(void*, int, void*, __IOHIDDevice*) + 74
3   com.apple.framework.IOKit     	0x00007fff30967fb0 __IOHIDManagerDeviceApplier + 764
4   com.apple.CoreFoundation      	0x00007fff2db80a12 __CFSetApplyFunction_block_invoke + 18
5   com.apple.CoreFoundation      	0x00007fff2db632d4 CFBasicHashApply + 124
6   com.apple.CoreFoundation      	0x00007fff2db809b0 CFSetApplyFunction + 128
7   com.apple.framework.IOKit     	0x00007fff30966a1b __ApplyToDevices + 105
8   com.apple.framework.IOKit     	0x00007fff30968203 __IOHIDManagerInitialEnumCallback + 39
9   com.apple.CoreFoundation      	0x00007fff2db85b81 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
10  com.apple.CoreFoundation      	0x00007fff2db85b20 __CFRunLoopDoSource0 + 103
11  com.apple.CoreFoundation      	0x00007fff2db69154 __CFRunLoopDoSources0 + 209
12  com.apple.CoreFoundation      	0x00007fff2db68760 __CFRunLoopRun + 1272
13  com.apple.CoreFoundation      	0x00007fff2db67fe3 CFRunLoopRunSpecific + 499
14  com.apple.HIToolbox           	0x00007fff2c6ef67d RunCurrentEventLoopInMode + 292
15  com.apple.HIToolbox           	0x00007fff2c6ef2c9 ReceiveNextEventCommon + 356
16  com.apple.HIToolbox           	0x00007fff2c6ef147 _BlockUntilNextEventMatchingListInModeWithFilter + 64
17  com.apple.AppKit              	0x00007fff2ad74864 _DPSNextEvent + 990
18  com.apple.AppKit              	0x00007fff2ad735d4 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1352
19  libpandagl.dylib              	0x00000001110ed544 CocoaGraphicsWindow::process_events() + 116
20  libpanda.1.10.dylib           	0x000000010e06dd5d GraphicsEngine::WindowRenderer::do_windows(GraphicsEngine*, Thread*) + 77
21  libpanda.1.10.dylib           	0x000000010e0696f2 GraphicsEngine::open_windows() + 978
22  libpanda.1.10.dylib           	0x000000010e068d4f GraphicsEngine::make_output(GraphicsPipe*, std::string const&, int, FrameBufferProperties const&, WindowProperties const&, int, GraphicsStateGuardian*, GraphicsOutput*) + 1935
23  core.cpython-37m-darwin.so    	0x000000010d184ef6 Dtool_GraphicsEngine_make_output_505(_object*, _object*, _object*) + 918
24  org.python.python             	0x000000010c96d560 _PyMethodDef_RawFastCallKeywords + 544
25  org.python.python             	0x000000010c971dd1 _PyMethodDescr_FastCallKeywords + 81
26  org.python.python             	0x000000010ca01f27 call_function + 801
27  org.python.python             	0x000000010c9fac57 _PyEval_EvalFrameDefault + 6396
28  org.python.python             	0x000000010c96ce8c function_code_fastcall + 112
29  org.python.python             	0x000000010ca01ef7 call_function + 753
30  org.python.python             	0x000000010c9fac57 _PyEval_EvalFrameDefault + 6396
31  org.python.python             	0x000000010c96ce8c function_code_fastcall + 112
32  org.python.python             	0x000000010c96d829 _PyObject_Call_Prepend + 150
33  org.python.python             	0x000000010c9aaf7d slot_tp_init + 80
34  org.python.python             	0x000000010c9a7c20 type_call + 172
35  org.python.python             	0x000000010c96c918 _PyObject_FastCallKeywords + 358
36  org.python.python             	0x000000010ca01ef0 call_function + 746
37  org.python.python             	0x000000010c9fad0b _PyEval_EvalFrameDefault + 6576
38  org.python.python             	0x000000010ca027a6 _PyEval_EvalCodeWithName + 1870
39  org.python.python             	0x000000010c9f92b8 PyEval_EvalCode + 51
40  org.python.python             	0x000000010ca2794b run_mod + 54
41  org.python.python             	0x000000010ca26975 PyRun_FileExFlags + 163
42  org.python.python             	0x000000010ca2601b PyRun_SimpleFileExFlags + 263
43  org.python.python             	0x000000010ca3e89e pymain_main + 5389
44  org.python.python             	0x000000010ca3ef80 _Py_UnixMain + 56
45  libdyld.dylib                 	0x00007fff650422e5 start + 1

When running the code in the debugger, we see that IOHIDDeviceCopyMatchingElements seems to return a null pointer, probably because it does not have access to the IOHIDDevice referenced, which cause in turn CFArrayGetCount try and dereference the null pointer.

The delay introduced by the debugger allows the system to print error messages :

TCC deny IOHIDDeviceOpen

And, after a few seconds, the system raised a popup warning that the Terminal app requested "Input monitoring" permission (It was actually Terminal, not Python or the name of the application, most probably because it was executed outside of an application bundle).

Input monitoring permission is a new permission introduced in Catalina, it is needed to have uncontrolled access to the input devices (e.g. the keyboard). I don't know if it can be explicitly requested by the code otherwise the code should be made robust and wait until the user gave the permission (or not) or abort and give an error to the user.

@el-dee

This comment has been minimized.

Copy link
Contributor Author

@el-dee el-dee commented Nov 28, 2019

From what I understood, from Catalina onwards using low level API to use input devices requires the "Input Monitoring" permission as using the low level API one can have access to the input even if the application does not have the focus (even if the app is not actually trying to access the input)

Now I'm not familiar at all with device management on Mac and how Panda use it, so I don't know what call exactly trigger the permission error.

With workaround #797, even if I refuse the permission, the application still works and the keyboard and the mouse are still responsive, so it's either the device inventory done in iotKitInputDevice, or some system keys that will not be available to Panda.

@el-dee

This comment has been minimized.

Copy link
Contributor Author

@el-dee el-dee commented Nov 28, 2019

Using gamepad example, I can confirm this is related to the retrieval of the device characteristics :

With "Input monitoring" enabled, I get the following log:

:device(debug): Discovered input device Apple Internal Keyboard / Trackpad (connected), mouse, 3 buttons, pointer
:device(debug): Discovered input device Apple Internal Keyboard / Trackpad (connected), keyboard, 277 buttons

Without, I only get the device name :

:device(debug): Discovered input device Apple Internal Keyboard / Trackpad (connected)
:device(debug): Discovered input device Apple Internal Keyboard / Trackpad (connected)
@rdb

This comment has been minimized.

Copy link
Member

@rdb rdb commented Nov 29, 2019

We use IOKit to access gamepad hardware (and raw mice/keyboards, but that is not so important). How does macOS want us to use the gamepad without access to a special permission? Did they introduce a new API for this?

@rdb rdb added bug macos labels Nov 29, 2019
@rdb rdb added this to the 1.10.5 milestone Nov 29, 2019
@el-dee

This comment has been minimized.

Copy link
Contributor Author

@el-dee el-dee commented Nov 29, 2019

According to this presentation https://developer.apple.com/videos/play/wwdc2019/616/, IOKit support of game controllers is deprecated, app should move too the high level Game Controller API But only Apple approved Gamepad seems to be supported : https://support.apple.com/en-us/HT210414

@el-dee el-dee changed the title MacOS: Catalina: Application crashes if it does not have access to input device permission MacOS: Catalina: Application crashes if it does not have "Input monitoring" permission Nov 29, 2019
@rdb

This comment has been minimized.

Copy link
Member

@rdb rdb commented Nov 30, 2019

Ah, that's the Apple we know and love (well, at least know); introducing a new API in the very release that breaks the old one.

Well, we should create a new issue for supporting the new API, and someone other than me will have to implement it since Catalina does not support my 2011 Mac Mini.

@el-dee

This comment has been minimized.

Copy link
Contributor Author

@el-dee el-dee commented Dec 2, 2019

Feature request created, see #801

@rdb

This comment has been minimized.

Copy link
Member

@rdb rdb commented Dec 3, 2019

@el-dee Would you mind preparing some instructions or some screenshots showing how to enable Input Monitoring permissions, so I can make a blog post warning users about this?

@el-dee

This comment has been minimized.

Copy link
Contributor Author

@el-dee el-dee commented Dec 3, 2019

Here are the screenshot and the instructions :

  1. Launch from the terminal any Panda3d application, for example samples/roaming-ralph

  2. After a couple of seconds, you will get the following popup :

Screenshot 2019-12-03 at 21 54 35

Note: f you don't have the patched version of Panda, your app will crash with a segfault error.

  1. Click on "Open System Preferences"

  2. If greyed out, unlock the panel by clicking on the lock on the lower left

Screenshot 2019-12-03 at 21 54 49

  1. Tick the check button next to Terminal and restart your Terminal to apply the security change.

Screenshot 2019-12-03 at 22 02 59

Screenshot 2019-12-03 at 22 03 51

  1. Open the Terminal again and launch your app again, it shouldn't crash anymore and be responsive.
@el-dee

This comment has been minimized.

Copy link
Contributor Author

@el-dee el-dee commented Dec 3, 2019

Two remarks:

It seems to work only if you are using Terminal.app

If you are using a compiled Panda3d application, the procedure is almost similar, except that you have to select your application in the security panel, and, weirdly, the checkbox is unticked a millisecond later, though your app will start correctly next time you launch it.

@rdb

This comment has been minimized.

Copy link
Member

@rdb rdb commented Dec 3, 2019

Thank you! To be clear, if Panda isn't patched, the dialog in step 2 will not show up at all? Or will Panda crash after clicking Deny?

@el-dee

This comment has been minimized.

Copy link
Contributor Author

@el-dee el-dee commented Dec 3, 2019

Panda crashes before or just at the same time as the dialog appears, that's why I think sometimes the dialog does not appear at all and the permission request is not displayed in the security panel.

@rdb

This comment has been minimized.

Copy link
Member

@rdb rdb commented Dec 12, 2019

Closing since I think #797 fixed this and #801 already tracks support for the new GameController API.

@rdb rdb closed this Dec 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.