核心音频用户-space 插件驱动程序 - 沙箱阻止来自另一个进程的数据交互
core audio user-space plug-in driver - sandbox preventing data interaction from another process
我正在开发一个基于示例的 coreaudio 用户-space 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 但仍然没有成功。
我还需要做些什么来完成这项工作吗(比如添加权利、代码签名)或者这不是正确的方法。?
我不确定 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 port = CFMessagePortCreateRemote(kCFAllocatorDefault, port_name);
端口的 return 值为 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
有人吗??
我很确定我 运行在我的 AudioServerPlugIn 中遇到了同样的问题。我可以查找并使用我尝试过的每一个 Mach 服务,除了我自己创建的服务。我创建的那些在常规过程中正常工作。
最后我读了 the Daemonomicon 并发现 coreaudiod
(托管 HAL 插件)正在使用全局 bootstrap 命名空间,但我的服务是在 per-用户 bootstrap 命名空间。因为 "processes using the global namespace can only see services in the global namespace" 我的插件看不到我的服务。
您可以使用 launchctl
来测试它,方法是让它 运行 注册您的服务的程序,但使用与 coreaudiod
相同的 bootstrap 命名空间。您可能需要禁用 rootless。
# launchctl bsexec $(pgrep coreaudiod) your_service_executable
有了那个 运行ning,再次尝试从您的插件连接。
从Daemonomicon 中的Table 2,您可以看到只有launchd 守护进程使用全局bootstrap 命名空间。这就解释了为什么 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. Note that without the UserName
/GroupName
keys your daemon will run as root. (The code for my service and plugin 也在该回购协议中,以防有帮助。)
不幸的是,我最终不得不使用 XPC,但我首先尝试了 CFMessagePort,它运行良好。
无论插件是否签名,似乎都可以正常工作。虽然,正如您所说,您确实需要 Info.plist.
中的 AudioServerPlugIn_MachServices
键
我正在开发一个基于示例的 coreaudio 用户-space 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 但仍然没有成功。
我还需要做些什么来完成这项工作吗(比如添加权利、代码签名)或者这不是正确的方法。? 我不确定 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 port = CFMessagePortCreateRemote(kCFAllocatorDefault, port_name);
端口的 return 值为 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
有人吗??
我很确定我 运行在我的 AudioServerPlugIn 中遇到了同样的问题。我可以查找并使用我尝试过的每一个 Mach 服务,除了我自己创建的服务。我创建的那些在常规过程中正常工作。
最后我读了 the Daemonomicon 并发现 coreaudiod
(托管 HAL 插件)正在使用全局 bootstrap 命名空间,但我的服务是在 per-用户 bootstrap 命名空间。因为 "processes using the global namespace can only see services in the global namespace" 我的插件看不到我的服务。
您可以使用 launchctl
来测试它,方法是让它 运行 注册您的服务的程序,但使用与 coreaudiod
相同的 bootstrap 命名空间。您可能需要禁用 rootless。
# launchctl bsexec $(pgrep coreaudiod) your_service_executable
有了那个 运行ning,再次尝试从您的插件连接。
从Daemonomicon 中的Table 2,您可以看到只有launchd 守护进程使用全局bootstrap 命名空间。这就解释了为什么 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. Note that without the UserName
/GroupName
keys your daemon will run as root. (The code for my service and plugin 也在该回购协议中,以防有帮助。)
不幸的是,我最终不得不使用 XPC,但我首先尝试了 CFMessagePort,它运行良好。
无论插件是否签名,似乎都可以正常工作。虽然,正如您所说,您确实需要 Info.plist.
中的AudioServerPlugIn_MachServices
键