Summary of the security discussions around Wayland and privileged clients
Martin Peres
martin.peres at free.fr
Wed Feb 19 08:11:03 PST 2014
Hi Guys,
Following to the giant and impossible to read "Authorized clients"
thread, I said I would take the time and write everything we talked
about down, for convenience and to check I took everyone's idea and
needs into account.
I published the whole article on my blog [1] but I also wanted to copy
the relevant information in this email, so as it could be easier for
people to comment inline (since I'm really interested in feedback here),
sorry for the markdown syntax but that's what I use for my website.
I added Martin Graesslin in CC because he has shown interest in this and
I'm sure his experience can benefit all of us.
Hope something close to this proposal will be satisfactory to everyone
and work can begin in this direction!
Cheers,
Martin Peres
[1]
http://mupuf.org/blog/2014/02/19/wayland-compositors-why-and-how-to-handle/
----------------------------------------------------------------------------------------------------------------------------------------------------------
#### Current state of security within Wayland compositors
The first good point of the Wayland protocol is input management. At the
moment, the protocol doesn't allow snooping on the input
(confidentiality), generating input events (integrity) nor for an
application to grab all events (availability). However, Wayland clients
allowing ``LD_PRELOAD`` are still vulnerable to input attacks, as
[demonstrated](https://github.com/MaartenBaert/Wayland-keylogger) by
Maarten Baert. This is not Wayland compositors' problem so it won't be
taken into account in this discussion.
Just like with X, there are multiple ways for applications to send their
output buffers to the graphics server. With Wayland/Weston, applications
can use shared memory (SHM) or GEM's buffer sharing mechanism. SHM
buffer sharing is meant for CPU-rendered application while GEM-based
buffer sharing is meant for GPU-rendered applications.
SHM buffer sharing seems to be using anonymous files and [file
descriptor(fd) passing](http://keithp.com/blogs/fd-passing/) in order to
transmit buffers from the client to the compositor. This makes sure that
only the creator and the receiver of the fd can access the (now-shared)
resource, making it impossible for a third-party other than the kernel
to spy on or modify the output of other applications (confused-deputy).
Confidentiality and integrity seems to be guaranteed but I haven't
dwelved into the implementation to make sure of it.
GEM buffer sharing [is known to be
insecure](http://www.x.org/wiki/Events/XDC2012/XDC2012AbstractHoegsberg+Peres+Ravier+Vetter/)
because shared buffers are referenced by a easily-guessable 32-bit
handle. Once the handle is guessed, the buffer can be opened by other
application run by the same user without access control. Once opened,
the buffers may be read from or written into. This means confidentiality
or integrity cannot be guaranteed on the output of applications using
this buffer-sharing method.
On-going work [is being
performed](http://lists.freedesktop.org/archives/Wayland-devel/2014-January/012727.html)
to make use of
[DMA-Buf](https://www.kernel.org/doc/Documentation/dma-buf-sharing.txt)
instead of GEM. DMA-Buf, just like SHM, is based on anonymous files and
fd-passing and even allows different GPU drivers to exchange GPU
buffers. Once the Wayland protocol and GPU applications start using it,
confidentiality and integrity of the output buffers won't be a problem
anymore.
+-----------------+---------+----------+
| Property | Input | Output |
+-----------------+---------+----------+
| Confidentiality | YES | WIP |
| Integrity | YES | WIP |
| Availability | YES | YES |
+-----------------+---------+----------+
#### The need for standardised privileged interfaces
Although Tim and I advised Wayland compositors [not to rely on external
programs](http://phd.mupuf.org/publication/2012/09/19/xdc2012_secu_recap/)
to perform privileged tasks, some people do think it is needed as they
want to make it possible to develop cross-compositors applications
performing privileged tasks. Examples of such applications would be:
- Screenshot applications (stills and video)
- Virtual keyboards and pointing devices
- Screen sharing (VPN, Skype)
- Hotkeys handlers (?)
- Session lockers
All of these applications are violating one or more security properties.
Wayland compositors should thus control the access to the interfaces
allowing those applications to work. Since we want these applications to
be cross-compositors, a standardised way of granting/passing/revoking
privileges should be described in the protocol or its implementation
reference guide.
#### Allowing the user to securely break security properties
By default, the system should be enforcing all the security properties
we defined earlier. However, sometimes, users need/want to automate some
process, record their screens or lock the computer with a custom-app.
This is why we need ways to by-pass the security when it is really
needed. Without such means, people may refuse to use Wayland because it
"takes freedom away from them". However an ideal design is so that
someone will always come up first with the "right" way to do something.
Here when it comes to distributors/vendors using Wayland, you want them
to use your own preferred security property rather than entirely
unlocking Wayland's safeguards to support the features of poorly-written
apps.
The usual way of dealing with applications needing more privileges is to
statically give them at launch time. Once an application has no use of
the permission anymore, it can revoke its right to access it, until its
next execution. This is very similar to what exists with
[capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html).
The problem with such a system is that a malicious application could
potentially take advantage of a poorly-coded application that holds an
interesting capability (assigned statically at launch time), and use
that application's capability to gain indirect access to the restricted
interface it is interested in. This is because permissions aren't
granted according to the immediate intent of the user. Indeed, a user
would ideally always have a way to be aware of a reduced security state.
This means the user has to take action in order to temporary reduce the
security. The user should then be able to check whether the system's
security is still reduced and should be able to revoke permissions.
Capturing the user's intent can be done by:
- Waiting for a user to press the key with a clear semantic before
launching the associated application (for instance, PrintScreen
launching the screen-shot application)
- Prompting the user whenever an application tries to access a
restricted interface
- Creating secure widgets that are drawn and managed by the compositor
but can be imported in applications
([UDAC](http://research.microsoft.com/pubs/152495/user-driven-access-control-nov2011.pdf))
- Any other way?
The first solution requires absolute trust in the input integrity and
requires the compositor to know which application it should run
(fullpath to the binary). The second solution requires both trust in
input integrity and output integrity (to prevent a malicious application
from changing the content of the prompt window to change its semantic
and turn it into a fake advertisement, for instance). The third solution
requires secure widgets, unfortunately it is -ENOTQUITETHEREYET. We have
ideas on how to implement them using sub-surfaces, they will be
discussed again later on this very same blog ;)
While I think the user-intent method has a higher security than static
privilege assignation, I think both should be implemented with the
latter used as a way for users to specify they are OK with potentially
reducing the security of the desktop environment to let the application
he/she wants to run properly. This will lower users' dissatisfaction and
should result in a better security than bypassing some security
properties for all applications. I am however worried that some stupid
applications may be OK with creating snapshot capabilities from the
command line, without requiring the user's input. A packager would then
grant the privileges to this application by default and thus, the mere
fact of having this application installed will make your desktop
non-confidential anymore.
This is why once privileges have been granted, the user needs to have a
way to keep track of who has access to restricted interfaces. This can
be done by having a mandatory notification when an application accesses
a privileged interface and a compositor-owned application in the systray
whose colour would indicate the current security state (no threat, at
least one application has the rights to use a restricted interface and
at least one application is using a restricted interface). A click on
this icon could provide more information about which restricted
interfaces are used by which application. A button could then be added
to each entry to allow users to revoke some privileges of applications.
While I think the interface for the application providing this feedback
should be specified, the user shouldn't have a choice on it and it
should be hardcoded in the Desktop Environment.
#### Recommendations to restricted Wayland interface designers
I have never designed an interface for Wayland and don't know what the
best practice is. However, I know that restricted interfaces should
never be considered as always usable.
The first important point is that before being able to use an interface,
a client should first bind to it. This binding process could either
succeed or fail, depending on the compositor's security policy. Clients
are mandated to test that binding worked well before using the
interface. In case it didn't, clients should fail gracefully and tell
the user what restricted interface couldn't be bound. Also, binding a
restricted interface could take some time and the application shouldn't
block on it.
To support privileges revocation, a revoke signal should be added to the
interface in order to inform clients their rights to access the
restricted interface have been revoked. Clients should fallback
gracefully and tell the user they received such a signal.
#### Launching privileged Wayland clients from the compositor
The most-secure way of launching clients requiring restricted interfaces
is to let the compositor run them by itself. This way, it can control
the environment in which the process has been launched which lowers the
risks of environment attacks such as the ``LD_PRELOAD`` one exposed earlier.
Implementing such a system is difficult as the compositor needs to
remember that the PID of the client it launched should be granted the
privileges to access one or more restricted interfaces when this
(soon-to-become)client connects to the Wayland compositor. Not only does
it mean that the compositor needs to have a separate table of which PIDs
are supposed to get which privileges, it also means the compositor needs
to keep track of the death of the client's PID to avoid another process
from re-using the PID of this client and gaining access to privileged
interfaces it wasn't supposed to access.
A simpler and more secure solution would be for the compositor to open a
UNIX socket to itself before exec'ing the client. Once opened, it should
be simpler for the compositor to set the client's capabilities to a flag
stored in the structure tracking the client and then execute the
client's binary. When running the exec() syscall, all the FDs that have
not been opened with the ``O_CLOEXEC``
[flag](http://linux.die.net/man/2/open) will be passed on to the new
process. A run-time parameter of the Wayland client could then be used
to tell which FD represents the unix socket to the Wayland compositor.
An example of such parameter could be ``--wayland-fd=xxx``. The
compositor should however be careful it doesn't leak any un-needed FD to
the new client.
#### Letting applications require more privileges at run time
Some times, application may require access to a restricted interface
after it has been launched. In this case, they can use the binding call
I described earlier and the compositor will grant access to it or not,
depending on its configuration or policy.
The problem with allowing applications to require more privileges is
that we do not control their environment and we cannot make sure it
didn't get loaded with ``LD_PRELOAD`` or tampered with in any other way.
As this decision really depends on which other security tools are being
used on the computer, this isn't something Wayland compositors should
hard-code. This leads us to our final proposal.
#### Wayland Security Modules
As seen earlier, granting access to a restricted interface or not
depends on the context of the client (how it was launched, previous
actions). The expected behaviour should be defined by a security policy.
As no consensus on the policy [can apparently be
reached](https://www.mail-archive.com/Wayland-devel@lists.freedesktop.org/msg12261.html)
(as usual in security), we have all agreed that we needed to separate
the policy from the code. This is very much alike [Linux Security
Modules
(LSM)](http://www.nsa.gov/research/_files/selinux/papers/module/x45.shtml)
or [X Access Control Extension
(XACE)](http://www.x.org/releases/X11R7.5/doc/security/XACE-Spec.html).
From a software engineering point of view, we would work on a security
library called Wayland Security Modules (name subject to changes) that
Wayland compositors would call when a security decision would need to be
made. The library would then load the wanted security policy, defined by
a shared-object that I will refer to as the security backend. In the
case of allowing a client to bind a restricted interface or not, the
corresponding WSM hook should return ``ACCEPT``, ``PROMPT`` or ``DENY``,
prompt meaning the compositor would have to ask the user if he wants to
accept the risk or not. Let me stress out that prompting should be a
last-resort measure as numerous studies have been made proving that
unless asked very rarely, users will always allow the operation.
Some additional hooks would also be needed in order to track the state
of Wayland clients (open, close, etc...) but nothing too major should be
needed. The compositors would just have to store this context in a
``void *security;`` attribute in the Wayland client structure. Finally,
WSM could be extended to control the access to the clipboard and maybe
other interfaces I haven't thought about yet.
The design of this library has not started yet. If you are interested in
helping out, I would love to have some feedback on what are your use
cases for WSM.
##### POSIX security backend
Most users run their computers without Mandatory Access Control (MAC),
it is thus important to provide the best security possible by default.
The POSIX security backend shouldn't depend on any decision engine or
MAC system (such as SELinux, Tomoyo, AppArmor, ...) and should be easy
to configure.
A default policy could be specified in ``/etc/wayland/security.conf``.
Per-client configuration could be stored in
``/etc/wayland/authorized_clients.d/``. This would allow package
managers to install application security policies along with the
application. Each application-specific policy would define the full path
of the allowed binary and which restricted interface the application
needs to get access to and in which cases is it acceptable (only when
run by the compositor? etc...). This is enables Trusted Path Execution
(TPE) as only the binary specified by the fullpath will match this set
of privileges.
Different UNIX users should be allowed to have different security
parameters. The easiest way would be to store per-user configuration in
different files in ``/etc/wayland/users.d/`` in order to simplify the
logic. Another possibility would be to have ``~/.wayland/`` overriding
the ``/etc/wayland/`` configuration folder. The latter solution would be
harder to implement securely because only the compositor should be
allowed to change the configuration.
In any case, to be considered valid, configuration files should all be
root-owned and 644 to prevent malicious applications from changing the
security policy. This means changing the security policy will be
considered as an administrative task which sounds about right.
##### Other security backends?
Other security backends could be implemented/integrated with
[PAM](http://www.linux-pam.org/),
[Polkit](http://www.freedesktop.org/wiki/Software/polkit/) or
[SELinux](http://www.nsa.gov/research/selinux/). You could even write
your own security backend without needing to patch any Wayland
compositor, unless you need new WSM hooks.
Please let me know about what security backend you would be interested in!
More information about the wayland-devel
mailing list