Leopard: AudioHardwareGetProperty on default output device doesn't work for setuid processes
Leopard: AudioHardwareGetProperty on default output device doesn't work for setuid processes
- Subject: Leopard: AudioHardwareGetProperty on default output device doesn't work for setuid processes
- From: "Ben Gertzfield" <email@hidden>
- Date: Tue, 30 Oct 2007 13:46:26 -0700
Hi folks,
I'm working on a bug where (on Leopard only) our software's audio always
plays sound out the default audio device, instead of the device the
user has selected in System Preferences. Our software uses a helper
background process that's set-uid root, as it needs to do privileged
operations.
I tracked the problem down to AudioHardwareGetProperty() always
returning AudioObjectID 0x10A (Built-in Output) on Leopard for
processes that are setuid root, no matter what the user has selected.
On Tiger, this works correctly for setuid root processes.
I've submitted bug 5568847 to track this issue, but I'm looking for a
workaround.
Does anyone know any possible workarounds for this issue? So far,
we've come up with:
1) Drop effective UID root process-wide before calling
AudioHardwareGetProperty(). We can't use this for our helper process,
as it needs to regain EUID root, and it's multithreaded, so we can't
affect other threads in the process.
2) Using fork() then seteuid(), then call AudioHardwareGetProperty().
We can't use this, as it spews hundreds of lines like:
The process has forked and you cannot use this CoreFoundation
functionality safely. You MUST exec().
Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__()
to debug.
3) Write a audio device helper program for our helper program. Use
fork(), then seteuid(), then exec the audio device helper program.
This solution is subpar, because we can't be notified of default audio
device changes, unless we either poll or set up a communication
protocol between the two processes.
Here's our test program that does workaround 1) above to demonstrate the bug.
===
#include <unistd.h>
#include <stdio.h>
#include <CoreAudio/CoreAudio.h>
void PrintDefaultOutputDevice(void)
{
AudioDeviceID device;
UInt32 size = sizeof device;
OSStatus err;
err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
&size,
&device);
printf("Got device id %lu\n", device);
if (err != noErr) {
fprintf(stderr, "Couldn't get default output device: %ld\n", err);
exit(1);
}
AudioObjectShow(device);
}
int main(int argc, char **argv)
{
printf("EUID is %d\n", geteuid());
PrintDefaultOutputDevice();
seteuid(getuid());
printf("EUID is %d\n", geteuid());
PrintDefaultOutputDevice();
return 0;
}
===
Here I'm running it on a Mac Pro running 10.5 (9A581), where the
selected audio device is "Built-in Line Output":
===
[beng@beng-macpro:~]% uname -a
Darwin beng-macpro 9.0.0 Darwin Kernel Version 9.0.0: Tue Oct 9
21:35:55 PDT 2007; root:xnu-1228~1/RELEASE_I386 i386
[beng@beng-macpro:~]% gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk
-framework CoreAudio -o coreAudioTestOnly coreAudioTestOnly.c
[beng@beng-macpro:~]% sudo chown root:wheel ./coreAudioTestOnly
[beng@beng-macpro:~]% sudo chmod 4755 ./coreAudioTestOnly
[beng@beng-macpro:~]% ./coreAudioTestOnly
EUID is 0
Got device id 266
AudioObjectID: 0x10A
Class: Audio Device
Name: Built-in Output
Input Channels: 0
Output Channels: 2
EUID is 5471
Got device id 264
AudioObjectID: 0x108
Class: Audio Device
Name: Built-in Line Output
Input Channels: 0
Output Channels: 2
===
And here I run the same program on a MacBook Pro running 10.4.10 (8R2232), where
the selected audio device is "USB Audio CODEC":
===
[beng@beng-macbookpro:~]% uname -a
Darwin beng-macbookpro 8.10.1 Darwin Kernel Version 8.10.1: Wed May 23
16:33:00 PDT 2007; root:xnu-792.22.5~1/RELEASE_I386 i386 i386
[beng@beng-macbookpro:~]% sudo chown root:wheel ./coreAudioTestOnly
[beng@beng-macbookpro:~]% sudo chmod 4755 ./coreAudioTestOnly
[beng@beng-macbookpro:~]% ./coreAudioTestOnly
EUID is 0
Got device id 260
AudioObjectID: 0x104
Class: Audio Device
Name: USB Audio CODEC
Input Channels: 0
Output Channels: 2
EUID is 501
Got device id 260
AudioObjectID: 0x104
Class: Audio Device
Name: USB Audio CODEC
Input Channels: 0
Output Channels: 2
===
Thanks,
Ben Gertzfield
_______________________________________________
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