• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: AudioUnit plugin vs. GarageBand sandboxing
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: AudioUnit plugin vs. GarageBand sandboxing


  • Subject: Re: AudioUnit plugin vs. GarageBand sandboxing
  • From: Christian Rober <email@hidden>
  • Date: Fri, 10 Apr 2015 23:38:01 -0400

Nicely done sir!

It is strange how IPC was not allowed, but shared POSIX memory was allowed.  I guess each app can choose which functionality to block, since apps other than GB worked.  Still its great to see you got it to work.

Yeah... the man page for pthread_rwlockatt_setspshared says that PTHREAD_PROCESS_SHARED is not supported under the BUGS section (i'm on 10.9.5 too).  That's a shame.  :(

I also could not find the man page for pthread_mutexattr_setspshared.  After a quick google search, it seems that the kernel may not REALLY implement that function.  You may not be getting the protection you expect, though I hope you are!

One small thing, I think your 2nd call to open will return EEXIST if there is a race and you lost to your other process.  My understanding is that create is "atomic", within kernel and with respect to the file descriptors.  In a create race condition one will fail and one will succeed (assuming all else is sound).  You may want to check errno in that case, but this race is probably super rare, if it exists at all.


On Fri, Apr 10, 2015 at 7:58 PM, Jeremy Friesner <email@hidden> wrote:
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

  • Follow-Ups:
    • Re: AudioUnit plugin vs. GarageBand sandboxing
      • From: Jeremy Friesner <email@hidden>
References: 
 >AudioUnit plugin vs. GarageBand sandboxing (From: Jeremy Friesner <email@hidden>)
 >Re: AudioUnit plugin vs. GarageBand sandboxing (From: Christian Rober <email@hidden>)
 >Re: AudioUnit plugin vs. GarageBand sandboxing (From: Jeremy Friesner <email@hidden>)

  • Prev by Date: Re: AudioUnit plugin vs. GarageBand sandboxing
  • Next by Date: Re: AudioUnit plugin vs. GarageBand sandboxing
  • Previous by thread: Re: AudioUnit plugin vs. GarageBand sandboxing
  • Next by thread: Re: AudioUnit plugin vs. GarageBand sandboxing
  • Index(es):
    • Date
    • Thread