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

How to use the new macOS kernel detach feature for non-root user #1014

Open
mcuee opened this issue Oct 30, 2021 · 40 comments
Open

How to use the new macOS kernel detach feature for non-root user #1014

mcuee opened this issue Oct 30, 2021 · 40 comments

Comments

@mcuee
Copy link
Member

mcuee commented Oct 30, 2021

The following pull request is an important new feature for libusb under macOS.

But it is not clear how to use it for non-root users. It is mentioned that "com.apple.vm.device-access" entitlement is needed. But there is no clear documentation from libusb or Apple on how to apply the entitlement

@mcuee
Copy link
Member Author

mcuee commented Oct 30, 2021

Apple documentation on USB driver development is very poor. And the documentation for the entitlement is also very poor.

https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_vm_device-access
https://developer.apple.com/documentation/bundleresources/entitlements

You configure entitlements for your app by declaring capabilities for a target in Xcode. Xcode records capabilities that you add in a property list file with the .entitlements extension. You can also edit the entitlements file directly. When code signing your app, Xcode combines the entitlements file, information from your developer account, and other project information to apply a final set of entitlements to your app.

@mcuee
Copy link
Member Author

mcuee commented Oct 30, 2021

#911 (comment)
@llinshenzhen

It's took me a while for reading history above, and a little bit confused. Is there any solution? macOS12 has released its official version, the libuvc still can't access camera anyhow. I did use the com.apple.vm.device-access in the entitlements.

Please tell what you have done and what is the outcome. Thanks.

@osy
Copy link
Contributor

osy commented Oct 30, 2021

@llinshenzhen You got the entitlement from Apple Developer support, created a provisioning profile with that entitlement, and built your app with that profile? Note that command line apps cannot use provisioning profiles and therefore cannot hold this entitlement.

@mcuee
Copy link
Member Author

mcuee commented Oct 30, 2021

You got the entitlement from Apple Developer support, created a provisioning profile with that entitlement, and built your app with that profile? Note that command line apps cannot use provisioning profiles and therefore cannot hold this entitlement.

@osy Great info. I've updated the FAQ here.
https://github.com/libusb/libusb/wiki/FAQ#how-can-i-run-libusb-applications-under-mac-os-x-if-there-is-already-a-kernel-extension-installed-for-the-device-and-claim-exclusive-access

@scchn
Copy link

scchn commented Oct 30, 2021

@osy Replied from Apple Developer Technical Support

Thanks for the links.  They helped me understand where you’re coming from.  
However, they do not change my conclusion.  
The `com.apple.vm.device-access` entitlement is intend for virtual machine (VM) apps.  
This is clearly called out on the entitlement name (the `vm` part) and in the documentation:

A Boolean value that indicates whether the app captures USB devices
and uses them in the guest-operating system.
                      ^^^^^^^^^^^^^^^^^^^^^^

AFAICT your app is not a VM app and thus it’s not eligible for this entitlement.

I'm using libuvc for my microscope software.

@mcuee
Copy link
Member Author

mcuee commented Oct 30, 2021

Replied from Apple Developer Technical Support

Thanks for the links.  They helped me understand where you’re coming from.  
However, they do not change my conclusion.  
The `com.apple.vm.device-access` entitlement is intend for virtual machine (VM) apps.  
This is clearly called out on the entitlement name (the `vm` part) and in the documentation:

A Boolean value that indicates whether the app captures USB devices
and uses them in the guest-operating system.
                      ^^^^^^^^^^^^^^^^^^^^^^

AFAICT your app is not a VM app and thus it’s not eligible for this entitlement.

I'm using libuvc for my microscope software.

@scchn
Can you ask Apple support what is the right entitlenent to use in that case? Thanks.

@zer0err
Copy link

zer0err commented Oct 30, 2021

@llinshenzhen You got the entitlement from Apple Developer support, created a provisioning profile with that entitlement, and built your app with that profile? Note that command line apps cannot use provisioning profiles and therefore cannot hold this entitlement.

I'm stuck at got an Entitlement from Apple, I checked the official website and emailed them about this, still waiting reply from them.

From official info as @scchn provided, it's might be not the correct solution of getting entitlement 'com.apple.vm.device-access' from Apple for those who needed to control and streaming UVC Camera inside macOS app. Kinda upset.

@zer0err
Copy link

zer0err commented Oct 30, 2021

#911 (comment) @llinshenzhen

It's took me a while for reading history above, and a little bit confused. Is there any solution? macOS12 has released its official version, the libuvc still can't access camera anyhow. I did use the com.apple.vm.device-access in the entitlements.

Please tell what you have done and what is the outcome. Thanks.

I added entitlement value 'com.apple.vm.device-access', and compiled libUSB turned on debug mode and confirmed that the entitlement or sudo privilege is needed. And 'sudo' can truly solved the problem, but as macOS app I needed entitlement solution other than sudo for better experience.

@scchn
Copy link

scchn commented Oct 30, 2021

@mcuee They only told me to file a bug about it...

If you have an existing app that no longer works on macOS 12 beta because of a USB access control change, my advice is that you file a bug about that.

@osy
Copy link
Contributor

osy commented Oct 30, 2021

I don’t think you guys understand… you don’t “get” the entitlement without Apple granting you a provisioning profile with it. Just adding it to your entitlements and ad-hoc signing it won’t work. This is impossible without Apple’s help.

@hjelmn
Copy link
Member

hjelmn commented Oct 30, 2021

My understanding is that this entitlement will be granted for non-VM Apps given that Apple is moving away from kernel-space drivers. If that is the case they really should change the name of the entitlement. Let us know what Apple says in their response.

@osy
Copy link
Contributor

osy commented Oct 30, 2021

I don’t think so. Apple has always held certain entitlements close to the chest.

@mcuee
Copy link
Member Author

mcuee commented Oct 31, 2021

I don’t think you guys understand… you don’t “get” the entitlement without Apple granting you a provisioning profile with it. Just adding it to your entitlements and ad-hoc signing it won’t work. This is impossible without Apple’s help.
Apple has always held certain entitlements close to the chest.

@osy
I understand this one. You need to be an Apple developer and get Apple's blessing for the provisioning profile.

Apparently "com.apple.vm.device-access" works in practice. The main question is whether "com.apple.vm.device-access" is the right entitlement or not. And we need Apple's answer for this one.

@mcuee
Copy link
Member Author

mcuee commented Oct 31, 2021

I added entitlement value 'com.apple.vm.device-com.apple.vm.device-accessaccess', and compiled libUSB turned on debug mode and confirmed that the entitlement or sudo privilege is needed. And 'sudo' can truly solved the problem, but as macOS app I needed entitlement solution other than sudo for better experience.

@llinshenzhen
If I understand your answer correctly, "com.apple.vm.device-access" entitlement does work. But why do you say that 'sudo' can TRULY solved the problem? You seem to indicate that "com.apple.vm.device-access" entitlement still have some issues? If that is the case, what are the issues?

'sudo' is probably just a work-around for testers like I since I am not an Apple developer, just a user/tester.

@zer0err
Copy link

zer0err commented Oct 31, 2021

I added entitlement value 'com.apple.vm.device-access', and compiled libUSB turned on debug mode and confirmed that the entitlement or sudo privilege is needed. And 'sudo' can truly solved the problem, but as macOS app I needed entitlement solution other than sudo for better experience.

@llinshenzhen If I understand your answer correctly, "com.apple.vm.device-access" entitlement does work. But why do you say that 'sudo' can TRULY solved the problem? You seem to indicate that "com.apple.vm.device-access" entitlement still have some issues? If that is the case, what are the issues?

'sudo' is probably just a work-around for testers like I since I am not an Apple developer, just a user/tester.

Thanks, your understanding is correct. 'sudo' can stream the UVC camera and able to control it, but same as you mention, this is not good enough. This workaround is inspired by libUSB source code:

      usbi_info (ctx, "no capture entitlements. may not be able to detach the kernel driver for this device");
      if (0 != geteuid()) {
        usbi_warn (ctx, "USB device capture requires either an entitlement (com.apple.vm.device-access) or root privilege");
        return LIBUSB_ERROR_ACCESS;
      }

About entitlement I'm facing 2 issues, firstly, as mentioned above this entitlement is for 'the guest-operating system', and second one is that this entitlement doesn't have open entry to request, can only contact Apple by email and I have no response from them so far.

Because end-users who upgraded their macOS to 12 can not control the camera we are selling, but other app like OBS can stream at least, we are facing lots of complaints.

@mcuee
Copy link
Member Author

mcuee commented Oct 31, 2021

About entitlement I'm facing 2 issues, firstly, as mentioned above this entitlement is for 'the guest-operating system', and second one is that this entitlement doesn't have open entry to request, can only contact Apple by email and I have no response from them so far.

You can not get around the second one as you can see from the answer from osy. Please try to get the first answer from Apple. Apparently it does work. It is just whether Apple will want to grant your request or not.

Because end-users who upgraded their macOS to 12 can not control the camera we are selling, but other app like OBS can stream at least, we are facing lots of complaints.

You may want to check how OBS works with USB cameras under macOS. In the end, libuvc/libusb may not be the right API to use if the system has already provided the video capture APIs. It seems to be more useful under Linux. libuvc main git tree does not even compile properly under Windows.

@shinya-ohtani
Copy link

shinya-ohtani commented Nov 2, 2021

I was using libuvc to conveniently test real-time processing of webcam images by importing them to my mac. However, when I upgraded to macOS Monterey for other reasons, I encountered a problem, and finally came to this issue.

If libusb will not be able to support macOS Monterey for a long time in the future, I will have to change my implementation to use other libraries, (but I have not been able to find a cross-platform library other than libuvc (+libusb) that can be used to import and control webcams.)

Is there any chance that libusb can overcome this problem?

@mcuee
Copy link
Member Author

mcuee commented Nov 2, 2021

I was using libuvc to conveniently test real-time processing of webcam images by importing them to my mac. However, when I upgraded to macOS Monterey for other reasons, I encountered a problem, and finally came to this issue.

If libusb will not be able to support macOS Monterey for a long time in the future, I will have to change my implementation to use other libraries, (but I have not been able to find a cross-platform library other than libuvc (+libusb) that can be used to import and control webcams.)

Is there any chance that libusb can overcome this problem?

Not so sure why you say libusb is not able to support macOS Monterey. It supports macOS Monterey properly.

As for libusb/libuvc for the UVC compatible cameras, apparently that is an Apple issue that they grab the device for exclusive access, unlike previous version of macOS. And apparently libusb git and libuvc work with macOS Monterey if you can get the provision profile from Apple for the "com.apple.vm.device-access" entitlement. The discussion is whether it is possible to get the approval or not as some Apple support personnel think it is not the right entitlement.

You need to be an Apple developer and contact Apple for help in this case. You can also file a bug report with Apple saying macOS Monterey does not work with devices previously working under earlier version of macOS. Maybe they will fix it.

On the other hand, libuvc does not seem to work well under Windows. Are you using libuvc under Windows? If you are already not using libuvc under Windows, then probably it is also okay not to use libuvc under macOS. Apparently new version of OBS Studio works under macOS Monterey and it does not use libuvc.

@wjh1987
Copy link

wjh1987 commented Nov 3, 2021

How do I obtain the com.apple.vm.device-access permission

@mcuee
Copy link
Member Author

mcuee commented Nov 3, 2021

How do I obtain the com.apple.vm.device-access permission

Answer from osy.
You got the entitlement from Apple Developer support, created a provisioning profile with that entitlement, and built your app with that profile. Note that command line apps cannot use provisioning profiles and therefore cannot hold this entitlement.

@shinya-ohtani
Copy link

I see. But, I'm in trouble. My App is a simple command line App for scientific experiments.

Since my app is built with cmake, I can create xcproject by adding "-G Xcode" to the cmake options, and then use xcode to build it with "com.apple.vm.device-access " entitlement in xcode.
I'll try this later, but it's inconvenient to not be able to build without relying on xcode.

@hjelmn
Copy link
Member

hjelmn commented Nov 4, 2021

Not sure that will help at all. cmake can generate a generic xcode project but it will take hand editing to make it work. cmake makes it seem easy but, like most things with cmake, it is far more complicated than that. I found this that may help:

https://stackoverflow.com/questions/57396522/setting-entitlements-on-executables

Looks like you need to create an Info.plist and embed it in your binary.

@osy
Copy link
Contributor

osy commented Nov 4, 2021

Reiterating my comment from above

Note that command line apps cannot use provisioning profiles and therefore cannot hold this entitlement.

Provisioning profiles != entitlements. Some entitlements do not need a provisioning profiles. This particular entitlement does.

@hjelmn
Copy link
Member

hjelmn commented Nov 4, 2021

@osy Ok, that makes sense. You need an embedded Info.plist to have any entitlements with a command line executable but this entitlement requires more than just that.

Keeps going back to thinking that it would be nice if Apple were to create a new entitlement for our purpose. We want the ability to provide user-space interaction of user-space devices that may have a matching kernel driver.

@zer0err
Copy link

zer0err commented Nov 4, 2021

How do I obtain the com.apple.vm.device-access permission

Answer from osy. You got the entitlement from Apple Developer support, created a provisioning profile with that entitlement, and built your app with that profile. Note that command line apps cannot use provisioning profiles and therefore cannot hold this entitlement.

This should be closed, cause Apple won't grant entitlement for non-vm system as they replied. And they won't answer any third-party issue detail either, like libusb. The only way to solve this is to ask user to authorize the app when you start, but that will bring other issues like, other cam will stop stream when you authorize your app to stream from libuvc. In all, if you are looking for solution to stream and control uvc camera the same time, libuvc is not the one you looking for.

@Dione520
Copy link

Don't use UVC to stream instead of sys native api, control the cam through protocol like HID to bypass this limitation is what I planning to do in the next.

Specific to UVC compatible devices like USB cameras with system built-in drivers, I actually agree that libuvc is not the right library to use. Apparently Apple may tighten up the access of these type of devices (probably things like keyboard, mouse, camera, audio devices) because of security/privacy concerns and the system will have exclusive access to the device. Therefore libusb/libuvc may not work.
BTW, for HID devices, we actually recommend HIDAPI as the cross-platform library to use.

Thanks for advice, I found another issue related to this that I need to use root privilege to access uvc camera when backward to macOS11 or older version. The libusb I'm using was compiled by latest source code on master branch, 1.0.24 released version or latest version on 'brew' doesn't work even I gave them the root privilege.

Usb access performance on different scenario as below

weird thing is when using the library compiled myself, it needs the root privilege on system version before macOS 12.😅

  Root privilege on macOS12 Root privilege before macOS12 Non-root privilege macOS12 Non-root before macOS12
Self compiled on master branch ✅ ✅ ✅ ✅
1.0.24 released / latest on brew ❌ ❌ ✅ ✅

You described that there is a self-compiled version of libuvc on the macOS12 system. Does it require root privileges? Is this done? I also encountered this problem. Could you please tell me about the latest development of libuvc&libusb under macOS12? (wuxiao1129@foxmail.com)

@DJing
Copy link

DJing commented Nov 29, 2021

libuvc is not the one you looking for.

Can you introduce other open source similar to libuvc。

Don't use UVC to stream instead of sys native api, control the cam through protocol like HID to bypass this limitation is what I planning to do in the next.

There is a workaround (for older mac versions other than Monterey for this entitlement issue). When opening the UVC, don't claim the USB interface. Only claim the USB interface right before write or read the UVC property and release it right after write/read.

For windows, the libuvc won't work for streaming and uvc control at same time, use Media Foundation (MF) or DirectShow (DS) instead.

@mcuee
Copy link
Member Author

mcuee commented Feb 6, 2022

I have updated the wiki here. It does not help to sort out the issue though -- I just try to document what we have now.
https://github.com/libusb/libusb/wiki/FAQ#How_can_I_run_libusb_applications_under_Mac_OS_X_if_there_is_already_a_kernel_extension_installed_for_the_device_and_claim_exclusive_access

@mcuee mcuee changed the title How to use the new macOS kernel detach feature for non-root user How to use the new macOS kernel detach feature for non-root user (no solution as of now for libuvc users) Jun 10, 2022
kleinerm added a commit to kleinerm/Psychtoolbox-3 that referenced this issue Nov 11, 2022
-> Test rebuild for claiming of interfaces on Windows.

Note that if a macOS kernel driver (kext) has already claimed exclusive access to the
device, then this will only work by detaching the kernel driver, which requires you
to run octave or matlab as root. Only tested by myself with octave via "sudo octave"
so far. For the hoops you have to jump through on macOS to get this working without
sudo, read this FAQ:

https://github.com/libusb/libusb/wiki/FAQ#how-can-i-run-libusb-applications-under-mac-os-x-if-there-is-already-a-kernel-extension-installed-for-the-device-and-claim-exclusive-access

Executive summary: Give up, or be prepared to suffer greatly!

Technical discussion thread which shows Apples "We don't care about this problem. Get lost!"
attitude to this problem, as of macOS 12 at least:

libusb/libusb#1014

=> Best hope is that your USB device does not have an associated kernel driver, otherwise things get really painful, or expensive and painful on macOS if one wants to use any data transfers
involving interface endpoints, e.g., USB bulk or interrupt transfers, to control USB devices.
@mcuee
Copy link
Member Author

mcuee commented Jan 24, 2023

Ultimate solution is to override the default USB video class extension

I asked this problem to the Apple, and they said:

Based on your request Apple Developer Technical Support believes that your question is answered by the Core Media I/O documentation page linked below:

Overriding the default USB video class extension: https://developer.apple.com/documentation/coremediaio/overriding_the_default_usb_video_class_extension?language=objc

Did someone try this?

This should work. Basically it is a bit similar to previously used method -- codeless kext, now it is codeless DriverKit extension. You do need to have the valid developer signature in order to load the extension.

Ref: https://developer.apple.com/documentation/systemextensions/installing_system_extensions_and_drivers?language=objc

During the activation process, the system verifies:

  • Your extension is installed in the Contents/Library/SystemExtensions folder of your app.
  • Your app is installed in an appropriate Applications directory of the system.
  • The code signature of your extension.
  • The entitlements in the code signature match the entitlements granted to your development team.
  • The identifer in your activation request matches the one in your system extension bundle.
  • The identifier isn’t already in use by another system extension.

The main drawback compared to previous situation is that it will no longer function as a UVC camera and you can only use libuvc. It may be okay for certain use cases though.

If possible, I think it is better not to use libusb/libuvc in this case. It was the same situation last time with HID device. Later HIDAPI project was launched to use native HID API under Mac OS X (now macOS). Maybe the application should use native macOS API now.

@Youw
Copy link
Member

Youw commented Feb 1, 2023

codeless kext

Deprecated on macOS 10.15 and fully obsolete on macOS 11.0.
Only System Extension path is possible today.

@mcuee mcuee changed the title How to use the new macOS kernel detach feature for non-root user (no solution as of now for libuvc users) How to use the new macOS kernel detach feature for non-root user (no easy solution as of now for libuvc users) Feb 16, 2023
@mcuee mcuee changed the title How to use the new macOS kernel detach feature for non-root user (no easy solution as of now for libuvc users) How to use the new macOS kernel detach feature for non-root user Feb 16, 2023
@mcuee
Copy link
Member Author

mcuee commented Feb 16, 2023

So now there is a solution for libuvc users and there is a success story here.

The idea may be similar for other types of device. I have closed $972 (specific to libuvc) but I will keep this issue open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants