Playing with libseccomp

Martin Gräßlin mgraesslin at kde.org
Sun Feb 19 12:17:11 UTC 2017


Hi all,

this weekend I spent some time on trying to get kscreenlocker_greet into 
a sandbox through libseccomp. My aim was to make it impossible for a lnf 
package to intercept the password and e.g. write it to a file.

In this mail I want to outline my findings.

First of all, what does libseccomp allow:
It is a filter on syscalls and you can filter on the arguments of the 
syscall. The filter can then allow, make it fail with errno, raise a 
signal or just crash.

My first approach was to install the filtering prior to any QtQuick 
interaction and deny all syscalls and whitelist the syscalls which are 
used. The approach utterly failed. After something like 40 syscalls I 
gave up on the approach as I still wasn't seeing the window.

Next approach: allow everything and deny the syscalls which would allow 
writing out the password. This kind of works, but not really.

We cannot disallow write as that is needed to wake up threads. So 
instead let's disallow open for files with write.

Problem 1: OpenGL needs to open /dev/dri/card* with write mode, which 
means QtQuick would fail. The seccomp filter does not allow to filter on 
the path in open. It can only compare pointer values but not pointer 
content. Thus I cannot check whether the path includes e.g. /dev/dri/ 
and allow that.

I solved this by ensuring Qt inits OpenGL prior to installing the 
seccomp filter.

At that point the greeter loaded and showed the view. I am able to see 
that my filter works as KSharedDataCache reports that it cannot open 
files for writing (fine).

But I'm not able to authenticate any more. The seccomp filter gets 
inherited to forked processes and cannot be disabled any more (the idea 
is that you cannot escape the sandbox). KScreenlocker forks+exec 
kcheckpass and that somehow opens a file in write mode for the pam 
interaction.

Kcheckpass only allows to be run once, so I cannot start it early 
enough.

At that point I'm currently stuck. I have huge problems understanding 
the kcheckpass source code, what it does and how to debug it.

I think the approach taken can work, but would need to change the PAM 
interaction. Given that our code is ancient, that would not be the worst 
thing to do.

So the lessons learned: libseccomp is difficult to use as the 
documentation is bad. The claim is that everything is documented, but 
it's documented in a way that it's obvious for the one familiar with it. 
For someone not familiar with libseccomp it's quite difficult to use.

An application interacting with OpenGL and DBus has too many syscalls to 
use a whitelist approach. Also we don't get to the fds we need to allow 
stuff for.

Seccomp needs to be installed quite late in the process. E.g. if we 
would want to use it in KWin_Wayland it would only make sense to install 
it after all the init work is done and the window manager is fully 
running.

How it could be used in future:
* in kscreenlocker it would be nice to solve the PAM interaction problem 
and then get open/write disabled also network access would be nice to 
get disabled
* in KWin_Wayland a disallow of open/write could also make sense once 
everything is started, but would only work once the kscreenlocker issue 
is resolved
* in KWin_Wayland disabling network access could be useful
* baloo could use it for the file extractors to prevent the 
Chrome+download vulnerability

Cheers
Martin


More information about the Plasma-devel mailing list