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 protected]> 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 protected]> 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 protected])
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/coreaudio-api/recapitch%40gmail.com
>
> This email sent to [email protected]
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/coreaudio-api/archive%40mail-archive.com
This email sent to [email protected]