plugins - 核心音频用户空间插件驱动程序 - 沙箱防止与另一个进程的数据交互

标签 plugins core-audio appstore-sandbox xpc mach

我正在基于示例开发 coreaudio 用户空间 hal 插件 developer.apple.com/library/mac/samplecode/AudioDriverExamples/Introduction/Intro.html

在插件实现中,我计划从另一个进程即CFMessagePort获取音频数据

但是,我在尝试创建端口 CFMessagePortCreateLocal 时在控制台中收到以下错误...

sandboxd[251]: ([2597]) coreaudiod(2597) 拒绝 mach 注册 com.mycompnay.audio

我做了一些谷歌搜索并找到了这篇文章

技术问答QA1811 https://developer.apple.com/library/mac/qa/qa1811/_index.html 关于在plist中添加AudioServerPlugIn_MachServices但仍然没有成功。

我还需要做些什么才能使这项工作正常进行(例如添加权利、代码签名),或者这不是正确的方法。? 我不确定 MesssagePort 机制在沙箱下是否还能工作。 XPC 服务可行吗?

非常感谢您抽出宝贵的时间。非常感谢任何帮助

<小时/>

更新1:

我应该在音频插件中创建一个远程端口而不是本地端口。话虽如此,使用 plist 中的 AudioServerPlugIn_MachServices 属性。现在控制台中没有 sandboxd[559]: ([552]) coreaudiod(552) Deny mach-lookup/register 消息。

但是,在我的音频 hal 插件(客户端)中,我有

CFStringRef port_name = CFSTR("com.mycompany.audio.XPCService"); CFMessagePortRef 端口 = CFMessagePortCreateRemote(kCFAllocatorDefault, port_name); 端口返回值 0。我在另一个应用程序中尝试过,效果很好。

这是我的服务器端:

CFStringRef port_name = CFSTR("com.mycompany.audio.XPCService");
CFMessagePortRef  port = CFMessagePortCreateLocal(kCFAllocatorDefault, port_name, &callback, NULL, NULL);
CFRunLoopSourceRef runLoopSource =
CFMessagePortCreateRunLoopSource(nil, port, 0);

CFRunLoopAddSource(CFRunLoopGetCurrent(),
                   runLoopSource,
                   kCFRunLoopCommonModes);
CFRunLoopRun();

我确实收到了一条与此相关的控制台消息。

com.apple.audio.DriverHelper[1314]:名为 SimpleAudioPlugIn.driver 的插件需要扩展名为 com.mycompnay.audio.XPCService 的 mach 服务的沙箱

有人知道为什么吗?

<小时/>

更新2

我注意到,当我使用 coreaudiod 的 Debug模式时,它确实成功获取了 mach 服务的对象引用。 (当我尝试 xpc_service 方法时也发生了同样的事情) project scheme setting

有人吗?

最佳答案

我很确定我的 AudioServerPlugIn 中遇到了同样的问题。我可以查找并使用我尝试过的每一个 Mach 服务,除了我创建的服务。我创建的那些可以按照常规流程正常运行。

最终我读到了the Daemonomicon并发现 coreaudiod (托管 HAL 插件)正在使用全局引导命名空间,但我的服务正在每用户引导命名空间中注册。由于“使用全局命名空间的进程只能看到全局命名空间中的服务”,我的插件无法看到我的服务。

您可以使用 launchctl 来测试这一点,方法是让它运行注册您的服务的程序,但使用与 coreaudiod 相同的引导命名空间。您可能需要禁用 rootless。

# launchctl bsexec $(pgrep coreaudiod) your_service_executable

运行后,尝试再次从您的插件连接。

从 Daemonomicon 的表 2 中,您可以看到只有 launchd 守护进程使用全局引导命名空间。这解释了为什么 coreaudiod 使用它。我认为这意味着您的 Mach 服务需要由 launchd 守护进程创建。

要制作一个,请创建一个 launchd.plist/Library/LaunchDaemons 中为您提供服务。将其所有者设置为 root:wheel 并使其只能由所有者写入。在其中设置 MachServices 键并添加您的服务名称:

<key>MachServices</key>
<dict>
    <key>com.mycompany.audio.XPCService</key>
    <true/>
</dict>

然后注册它:

# launchctl bootstrap system /Library/LaunchDaemons/com.mycompany.audio.XPCService.plist

这就是我最终得到的结果:com.bearisdriving.BGM.XPCHelper.plist.template 。请注意,如果没有 UserName/GroupName 键,您的守护进程将以 root 身份运行。 (my serviceplugin 的代码也位于该存储库中,以防有帮助。)

不幸的是,我最终不得不使用 XPC,但我首先尝试了 CFMessagePort,效果很好。

无论插件是否签名,似乎都工作正常。不过,正如您所说,您确实需要 Info.plist 中的 AudioServerPlugIn_MachServices 键。

关于plugins - 核心音频用户空间插件驱动程序 - 沙箱防止与另一个进程的数据交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33138275/

相关文章:

objective-c - 如何设置 kAudioUnitSubType_Distortion

ios - 将 AUNode 效果连接为发送类型而不是插入类型

macos - 用于在沙盒环境中激活其他应用程序的菜单项的 CGEventPostToPSN() 替代方案?

ios - 将文件从主包复制到文档目录(沙箱)

javascript - 如何检测 Chrome(和其他)中是否启用了 native FlashBlock?

c# - DLL的动态加载

jquery - 插件中的 Google Analytics 代码

iphone - 用 AVAssetReader 擦洗

java - Eclipse 插件的国际化

objective-c - Mac 应用程序沙盒和 forkpty()