Re: Leopard: AudioHardwareGetProperty on default output device doesn't work for setuid processes
Re: Leopard: AudioHardwareGetProperty on default output device doesn't work for setuid processes
- Subject: Re: Leopard: AudioHardwareGetProperty on default output device doesn't work for setuid processes
- From: Jeff Moore <email@hidden>
- Date: Tue, 30 Oct 2007 14:49:50 -0700
On Oct 30, 2007, at 1:46 PM, Ben Gertzfield wrote:
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.
The default device is a per-user setting, not a per-machine setting.
So a process owned by root is going to potentially have a different
default device than one owned by some other user.
On Tiger, this works correctly for setuid root processes.
I just checked with HALLab. I see a different default device for the
root user than for some other user.
Note that the HAL's per-user settings will get confused in a program
that calls seteuid(). This is because CFPreferences, the mechanism the
HAL uses to store and retrieve the default device setting, has no way
of know about the change in effective user ID. Consequently, your
program needs to flush the CFPreferences caches manually.
Alternately, there is also a property on the HAL's system object (that
for some inexplicable reason is not in the public API) with the 4CC
'euid' that you can set to inform the HAL that you have called
seteuid(). The value for the property is a UInt32, but the contents
has no defined meaning. The act of setting it is all that is important.
Note that on Leopard, the HAL has a different mechanism for figuring
out the euid of a process which works around the need to tell it about
the change in euid. This is likely why your code is now failing.
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?
You need a new scheme to manage the default device for your privileged
process. There's no way this will ever work the way you have described
it. Since the privileged process is acting on behalf of a non-
privileged user, you need to have the process that spawns the
privileged process push the appropriate per-user settings to it.
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.
If you want to know the default device for a particular user, you have
to pose the question from a process owned by that user. There is no
other way to do it. In your case, you'll need to figure some way to
get the default device for a user and push it over to your privileged
process.
On the other hand, this might be a good time to re-evaluate why you
need a privileged process in the first place.
--
Jeff Moore
Core Audio
Apple
_______________________________________________
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