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