Re: AudioUnit plugin vs. GarageBand sandboxing
Re: AudioUnit plugin vs. GarageBand sandboxing
- Subject: Re: AudioUnit plugin vs. GarageBand sandboxing
- From: Jeremy Friesner <email@hidden>
- Date: Fri, 10 Apr 2015 16:58:31 -0700
Hi Christian,
After a lot more hacking around, I was able to find a method that would more-or-less work under GarageBand’s sandbox restrictions. I execute code like the following in both my companion app and the AudioUnit plugin:
1) Create (or open, if it already exists) a file in /tmp that is the appropriate size:
_mmapFilePath = _areaName.Prepend("/tmp/");
_shmFD = open(_mmapFilePath(), O_RDWR); // see if it already exists first
if ((_shmFD < 0)&&(createSize > 0))
{
_shmFD = open(_mmapFilePath(), O_RDWR|O_CREAT|O_EXCL); // if it didn't exist, we'll create it (race condition here?)
if (_shmFD >= 0)
{
_isCreatedLocally = true;
if (fchmod(_shmFD, S_IRWXU|S_IRWXG|S_IRWXO) != 0) perror("fchmod");
if (ftruncate(_shmFD, SHARED_MEMORY_HEADER_SIZE+createSize) != 0) perror("ftruncate");
}
}
2) mmap() that file into memory:
_area = mmap(NULL, _areaSize, PROT_READ|PROT_WRITE, MAP_SHARED, _shmFD, 0);
3) Initialize a mutex in the shared memory region, with PTHREAD_PROCESS_SHARED attribute:
pthread_mutex_t * mutex = (pthread_mutex_t *) _area;
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) != 0) perror("pthread_mutexattr_init");
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED) != 0) perror("pthread_mutexattr_setpshared");
if (pthread_mutex_init(mutex, &attr) == 0) {…}
…. and at that point the shared memory area is usable for me (under MacOS/X 10.9.5). Why this works and the other APIs are forbidden is a mystery to me, as they both do approximately the same thing.
Note that I originally wanted to use a pthread read/write locker (e.g. via pthread_rwlockattr_init()) rather than a mutex, but for some reason I couldn’t get it to work reliably; if process A had the locker locked and process B tried to lock it, process B’s pthread_rwlock_rdlock() or pthread_rwlock_wrlock() would return non-zero (indicating an error), but perror() would only report “Undefined Error”.
-Jeremy
On Apr 6, 2015, at 8:07 PM, Christian Rober <email@hidden> wrote:
> Hi Jeremy,
>
> Interesting question; I was just working on socket communications between my OSX hosted audio unit and my other parallel app...
>
> First, have you seen this doc (and associated children docs)?
>
> https://developer.apple.com/library/mac/technotes/tn2312/_index.html
>
> I noticed that you can add plist items to declare the use of certain kernel features. Maybe if you add the right key Garage Band (or the kernel) will change the permissions at runtime? Or it may just block your AU outright, which would at least corroborate your other observations. It may be worth following one of the guides that shows you how to variously re-sandbox AULab and probe it in the debugger with your AU attached.
>
> You may have already seen this (bottom of doc):
>
> https://developer.apple.com/library/mac/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW24
>
> My reading: Unless there is some way to use Garage Band's group name, and use only POSIX shared memory, then your design does not seem possible with a sandboxed host. Have you tried determining GB's group name and adding that entitlement to your secondary app? Assuming the semget error is occurring in the AU, there may still need to be some symmetry between the GB process and your secondary app.
>
> My other thought is that plain old sockets would be too slow for audio rendering cycles, otherwise you would have tried them already. They may have the same issue though without entitlements added.
>
> Lastly, regarding the documentation: I have never tried creating an XPC service. I assume it would need to be created by the owners of a given signed/sandboxed app (i.e. Garage Band), and there would have to be a host-provided, corresponding library/SDK to link your AU against. But that is just a guess, and a service may be too slow compared to typical shared memory access for your needs.
>
> Hopefully someone who has more experience with sandboxed audio IPC can jump in...?
>
> --Christian
>
> On Mon, Apr 6, 2015 at 10:07 PM, Jeremy Friesner <email@hidden> wrote:
> Hi all,
>
> I’ve written a little AudioUnit effects plugin that uses a semaphore and a shared memory region in order to communicate audio data to/from a companion application. (it does this because only the companion application has access to all of the contextual information necessary to process the audio properly)
>
> This plugin works fine under some 3rd party applications that support AudioUnit effects plugins, but when I try to use it within GarageBand, it fails to initialize. On investigation, this I found that it fails because because semget() returns -1 and sets errno to EPERM.
>
> I’m pretty sure that is because newer versions of GarageBand run the plugin code inside a sandbox for security reasons.
>
> My question is — is there any way to either get GarageBand to run the plugin without the sandbox restrictions, or for my plugin to request permission to use a semaphore and shared memory despite the sandbox? Or am I just out of luck here?
>
> Thanks,
> Jeremy
>
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Coreaudio-api mailing list (email@hidden)
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden