Hmm, Apparently I missed this post when it first appeared a few weeks ago - anyhow, I know Ricardo is also scetching on some type of security, so he's cc:ed now. I also remember discussing the sync/async issues with him, but I'm not totally sure what we ended up with, and I also don't know how far Ricardo has come when it comes to implementing it. Ricardo, can you fill in on the details? // David On 2015-02-23 16:26, Wim Taymans wrote: > Hi all, > > I've been experimenting with adding access control to pulseaudio and I would > like to start the discussion and propose some ideas with the attached patch > set. > > With the current pulseaudio policy, once the app has made a connection with the > daemon, it can perform any action it wants. This includes inspecting the state > of the various objects but more problematically, the client is allowed to > change the volume of any stream or sink/source or even kill any stream in the > daemon. Any client is also allowed to start capturing from any of the sources > or even the monitor sources of other streams. This is not something we want to > allow in all cases without explicitly asking the user first. > > The primary use case for access control is sandboxed apps where we want to > restrict the actions that the sandboxed app can perform on pulseaudio. We > currently bind mount the pulseaudio socket in the sandbox and let the clients > use that to communicate over the native protocol with the pulseaudio daemon > [1]. This is the only way to communicate with pulseaudio, so the cli protocol > and other protocols are disabled and excluded from this discussion. > > Pulseaudio was not designed and built with access control in mind from the > start. Adding full control at the lowest level is probably not feasable at this > stage, and I believe it is not really needed. Instead, I've experimented with > blocking access at the protocol-native level [2]. > > With the native protocol, there are about 39 interesting actions that a client > can perform. These roughly map to the pa_context, introspection, sample cache > and pa_stream API. The idea is to fire a hook for each of these commands to > check if the object being operated on can be seen/modified by the requesting > client. The implementation of these checks happens in modules that can > implement whatever policy is needed by connecting to the various hooks. This > makes for some simple extra additions in protocol-native.c > > For the subscribed events, we need to be carefull that we don't send events to > clients about objects that the client is not allowed to see, like an > input_stream of some other client, if the policy does not allow that. It's a > little tricky because with the REMOVE event, we can't get to the original > object anymore (to check who the owner was, for example). This can be solved by > keeping a list of all the events sent to a client about what objects, as is > implemented in [2]. > > There are more actions in the pa_stream object but I believe it is not very > useful to control access to those. Those actions are about configuring the > stream attributes and get status information about the streams. I believe it is > sufficient to allow or deny the creation of the pa_stream and after that, you > are free to use all pa_stream actions on that stream. again, moving the stream > to another sink is something that can be blocked, if needed because it is not > an action on the pa_stream. > > What we eventually might want to do is ask the user for permission before a > potentially dangerous action is done (record from a source, switch > sinks/source,...). The idea is to let the access module call into a dbus api > that will handle the user interaction and tells us what to do next. We would > then also need to store those results in a database so that we don't have to > ask for permission every time. I'm not sure we can block those protocol-native > calls while waiting for the user or if we have to make them async on the server. > > [2] contains a simple example access module that has some hardcoded checks on > input/output sink/source to see if the streams belong to the client that > created them. This essentially makes each client only see its own streams and > disallows any action on a stream that's not from the client. The idea is to do > different checks based on the user/cgroup/... a process is executed under, > possibly configured with a config file somehow. > > What do you think? I would love to hear your ideas. > > [1] https://wiki.gnome.org/action/info/Projects/SandboxedApps/Sandbox > [2] http://cgit.freedesktop.org/~wtay/pulseaudio/log/?h=access-hooks > > Wim Taymans (2): > access: add access control hooks > module-access: make policy object containing rules > > src/Makefile.am | 8 + > src/modules/module-access.c | 354 ++++++++++++++++++++++++++++++++++++++++ > src/pulsecore/access.h | 98 +++++++++++ > src/pulsecore/core-subscribe.c | 2 +- > src/pulsecore/core.c | 5 + > src/pulsecore/core.h | 3 + > src/pulsecore/protocol-native.c | 152 +++++++++++++++++ > 7 files changed, 621 insertions(+), 1 deletion(-) > create mode 100644 src/modules/module-access.c > create mode 100644 src/pulsecore/access.h > -- David Henningsson, Canonical Ltd. https://launchpad.net/~diwic