【问题标题】:core audio user-space plug-in driver - sandbox preventing data interaction from another process核心音频用户空间插件驱动程序 - 沙箱防止来自另一个进程的数据交互
【发布时间】:2016-01-13 07:20:10
【问题描述】:

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

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

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

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

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

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

我还需要做些什么来完成这项工作(例如添加权利、代码签名)或者这不是正确的方法。? 我不确定 MessagePort 机制在沙箱下是否可以工作。 XPC 服务是否可行?

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


更新 1:

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

但是,在我的音频 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

有人吗??

【问题讨论】:

标签: plugins core-audio appstore-sandbox xpc mach


【解决方案1】:

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

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

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

# launchctl bsexec $(pgrep coreaudiod) your_service_executable

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

从 Daemonnomicon 中的表 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 键。

【讨论】:

  • 感谢@freshtop 以非常描述性的方式回复。我能够使 XPC 以与您在此处建议的方式略有不同的方式进行通信(不确定这是否合适)。我在 int main(int argc, const char * argv[]) 中间过程中创建了基于 C 的 xpc 函数。 sudo chown root 是否在 /LaunchDaemons 中使用我的 plist。我将花一些时间查看您的示例。非常感谢您的回答。顺便说一句,CFMessagePort 从来没有为我工作过。如果是这样就太好了。
  • 我似乎仍然无法正常工作(一年后)。我已经多次梳理了背景音乐和这个答案,但我仍然看到可怕的 requires extending the sandbox for the mach service 错误并且没有连接。权限似乎是正确的,所有权似乎是正确的,launchd 已被验证在 XPC 服务上工作,并且它使用 launchctl bootstrap system /System/LaunchDaemons/my.service.plist 引导至无恶意。 :|我已经束手无策了。
  • 为什么最终不得不使用 XPC 而不是 CFMessagePort?
  • @RuurdAdema 不确定,抱歉。实际上,我最近重读了这个答案并问了自己同样的问题。我使用 XPC 的主要目的是在 StartIO 中阻塞,直到另一个进程告诉我的插件它可以启动 IO,所以我的猜测是,直到我让 StartIO 返回后,我才能收到来自 CFMessagePort 的回复.也就是说,仅从文档中,我不明白为什么我无法在不同的线程上收到回复。
  • CFMessagePort 不适用于 Catalina,我正在努力让 XPC 正常工作
猜你喜欢
  • 2020-10-30
  • 1970-01-01
  • 2017-01-04
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
  • 2023-03-08
相关资源
最近更新 更多