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 protected]> 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 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]
