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

时间:2015-10-15 01:21:34

标签: 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)deny mach-register com.mycompnay.audio

我做了一些googlging并来到这篇文章

技术Q& A 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 消息。

然而,在我的audio hal插件(客户端)我有

CFStringRef port_name = CFSTR("com.mycompany.audio.XPCService"); CFMessagePortRef port = 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的调试模式时,它成功获得了mach服务的对象引用。 (当我尝试xpc_service方法时,同样的事情发生了) project scheme setting

任何??

1 个答案:

答案 0 :(得分:4)

我很确定我在AudioServerPlugIn中遇到了同样的问题。我可以查看并使用我尝试过的每一个Mach服务,除了我创建的服务。我创建的那些工作通常来自常规流程。

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

您可以使用launchctl来运行注册您的服务的程序,但使用与coreaudiod相同的引导名称空间来测试它。您可能需要禁用无根。

# launchctl bsexec $(pgrep coreaudiod) your_service_executable

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

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

要创建一个,请在/Library/LaunchDaemons中为您的服务创建launchd.plist。将其所有者设置为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密钥。