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

Plugins 核心音频用户空间插件驱动程序-防止来自另一进程的数据交互的沙箱,plugins,core-audio,appstore-sandbox,xpc,mach,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 ma

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

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

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

sandboxd[251]:([2597])coreaudiod(2597)deny mach register com.mycopnay.audio

我搜索了一下,找到了这篇文章

技术问答QA1811 关于在plist中添加AudioServerPlugIn\u服务,但仍然没有成功

我还需要做些什么来实现这一点(比如添加权利、代码符号),或者这不是正确的方法。? 我不确定MessagePort机制在沙箱下是否还能工作。XPC服务是否可行

非常感谢您抽出时间。非常感谢您的帮助


更新1:

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

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

CFStringRef port_name=CFSTR(“com.mycompany.audio.XPCService”);
CFMessagePortRef port=CFMessagePortCreateRemote(kCFAllocatorDefault,端口名称);
端口已返回值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]:名为simpleudioplugin.driver的插件需要扩展名为com.mycopnay.audio.XPCService的mach服务的沙盒

有人知道为什么吗


更新2

我注意到,当我使用coreadiod的调试模式时,它确实成功地获得了mach服务的对象引用。(我尝试xpc_服务方法时也发生了同样的事情)


任何人???

我很确定我在AudioServerPlugIn中遇到了同样的问题。我可以查找并使用我尝试过的每一种马赫数服务,除了我创建的服务。而我所创建的程序通常是通过一个常规的过程来工作的

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

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

# launchctl bsexec $(pgrep coreaudiod) your_service_executable
运行后,再次尝试从插件连接

从守护进程图标中的表2可以看出,只有已启动的守护进程使用全局引导命名空间。这就解释了为什么
coreadiod
使用它。我认为这意味着你的Mach服务需要由一个启动的守护进程创建

要创建一个,请在
/Library/LaunchDaemons
中为您的服务创建一个。将其所有者设置为
root:wheel
,并使其仅可由所有者写入。在其中,设置
MachServices
键并添加服务名称:

<key>MachServices</key>
<dict>
    <key>com.mycompany.audio.XPCService</key>
    <true/>
</dict>
这就是我的结局:。请注意,如果没有
UserName
/
GroupName
键,守护进程将以root用户身份运行。(和的代码也在回购协议中,以防有用。)

不幸的是,我最终不得不使用XPC,但我先尝试了CFMessagePort,它工作得很好


无论插件是否签名,似乎都可以正常工作。不过,正如您所说,您确实需要在Info.plist中输入
AudioServerPlugIn\u MachServices
键。

Hi Allen,正在尝试设置调试。首先,您是如何使用coreaudiod进行调试的?我一直收到“错误:连接失败:失去连接”的消息…@Robert我在这里得到了我的信息:谢谢@Allen,我终于通过在恢复操作系统模式下设置“csrutil disable”让它工作了,这样就可以调试coreaudiod了!:)感谢@freshtop以非常描述性的方式回复。我能够使XPC以一种与您在这里建议的稍有不同的方式进行通信(不确定这是否是合适的方式)。我在int-main(int-argc,const-char*argv[])中间进程中创建了基于C的xpc函数。sudo chown用我的plist启动了守护进程。我将花一些时间复习一下你的例子。非常感谢你的回答。顺便说一句,这个CFMessagePort对我从来都不起作用。如果真是这样的话,那就太好了。我(一年后)似乎仍然无法让它工作。我已经梳理了背景音乐和这个答案好几次了,我仍然看到可怕的
需要扩展沙箱以获得马赫服务
错误和无连接。权限似乎是正确的,所有权似乎是正确的,launchd被验证为在XPC服务上工作,并且它是使用
launchctl引导系统/system/LaunchDaemons/my.service.plist引导的,无avil.:我真是不知所措。为什么你最终不得不使用XPC而不是CFMessagePort?@RuurdAdema不确定,抱歉。事实上,我最近重读了这个答案,问了自己同样的问题。我使用XPC的主要目的是阻止StartIO,直到另一个进程告诉我的插件它可以启动IO,所以我猜在我让StartIO返回之前,我无法收到来自CFMessagePort的回复。也就是说,仅仅从文档中,我不明白为什么我不能在不同的线程上收到回复。CFMessagePort不能与Catalina一起工作,我在ge上苦苦挣扎
# launchctl bootstrap system /Library/LaunchDaemons/com.mycompany.audio.XPCService.plist