Bug 384651 - kscreenlocker fails SeccompTest with glibc 2.26
Summary: kscreenlocker fails SeccompTest with glibc 2.26
Status: RESOLVED FIXED
Alias: None
Product: kscreenlocker
Classification: Plasma
Component: general (show other bugs)
Version: unspecified
Platform: Ubuntu Linux
: NOR major
Target Milestone: ---
Assignee: Plasma Bugs List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-13 07:44 UTC by Rik Mills
Modified: 2017-09-13 18:27 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rik Mills 2017-09-13 07:44:17 UTC
The SeccompTest tests fails on ubuntu (and OpenSuse it seems) with glibc 2.26

version 5.10.5.1

**** failure log ****

Tested on ubuntu infra and loaclly, and is a current blocker to glibc transition in 17.10 (Artful).

e.g. the glibc triggers on http://autopkgtest.ubuntu.com/packages/k/kscreenlocker/artful/amd64

autopkgtest [01:58:51]: test testsuite: [-----------------------
Openbox-Message: Unable to find a valid menu file "/var/lib/openbox/debian-menu.xml"
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-ubuntu'
kbuildsycoca5 running...
	make -j1 test ARGS\+=-j1
Running tests...
/usr/bin/ctest --force-new-ctest-process -j1
Test project /tmp/autopkgtest.EC2Co9/build.Eu3/kscreenlocker-5.10.5.1/obj-x86_64-linux-gnu
    Start 1: ksmserver-authenticatorTest
1/5 Test #1: ksmserver-authenticatorTest ......   Passed    3.15 sec
    Start 2: kscreenlocker-seccompTest
2/5 Test #2: kscreenlocker-seccompTest ........***Failed    0.16 sec
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-ubuntu'
********* Start testing of SeccompTest *********
Config: Using QtTest library 5.9.1, Qt 5.9.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 7.1.0)
OpenGL vendor string:                   VMware, Inc.
OpenGL renderer string:                 llvmpipe (LLVM 4.0, 256 bits)
OpenGL version string:                  3.0 Mesa 17.2.0-rc4
OpenGL shading language version string: 1.30
Driver:                                 Unknown
GPU class:                              Unknown
OpenGL version:                         3.0
GLSL version:                           1.30
Mesa version:                           17.2
Linux kernel version:                   4.12
Requires strict binding:                yes
GLSL shaders:                           yes
Texture NPOT support:                   yes
Virtual Machine:                        no
PASS   : SeccompTest::initTestCase()
FAIL!  : SeccompTest::testCreateFile() '!file.open()' returned FALSE. ()
   Loc: [/tmp/autopkgtest.EC2Co9/build.Eu3/kscreenlocker-5.10.5.1/greeter/autotests/seccomp_test.cpp(54)]
FAIL!  : SeccompTest::testOpenFile() '!file.open(QIODevice::WriteOnly)' returned FALSE. ()
   Loc: [/tmp/autopkgtest.EC2Co9/build.Eu3/kscreenlocker-5.10.5.1/greeter/autotests/seccomp_test.cpp(64)]
QWARN  : SeccompTest::testStartProcess() QProcessPrivate::createPipe: Cannot create pipe 0x3899b97968: Operation not permitted
PASS   : SeccompTest::testStartProcess()
PASS   : SeccompTest::testNetworkAccess(domain)
PASS   : SeccompTest::testNetworkAccess(ip4)
PASS   : SeccompTest::testNetworkAccess(ip6)
PASS   : SeccompTest::cleanupTestCase()
Totals: 6 passed, 2 failed, 0 skipped, 0 blacklisted, 105ms
********* Finished testing of SeccompTest *********

    Start 3: ksmserver-logindTest
3/5 Test #3: ksmserver-logindTest .............   Passed    0.22 sec
    Start 4: ksmserver-x11LockerTest
4/5 Test #4: ksmserver-x11LockerTest ..........   Passed    9.31 sec
    Start 5: ksld-noScreensTest
Activating service name='org.kde.kglobalaccel'
Activated service 'org.kde.kglobalaccel' failed: Failed to execute program org.kde.kglobalaccel: No such file or directory
Activating service name='org.kde.kglobalaccel'
Activated service 'org.kde.kglobalaccel' failed: Failed to execute program org.kde.kglobalaccel: No such file or directory
Activating service name='org.kde.kglobalaccel'
5/5 Test #5: ksld-noScreensTest ...............   Passed    0.07 sec

80% tests passed, 1 tests failed out of 5

Total Test time (real) =  12.92 sec

The following tests FAILED:
	  2 - kscreenlocker-seccompTest (Failed)
Errors while running CTest
Makefile:120: recipe for target 'test' failed
Comment 1 Fabian Vogt 2017-09-13 07:54:22 UTC
stracing the test shows a succeeding call to openat, which is not supposed to happen.
This is fixed (and the make test run confirms that) with this change:

diff --git a/greeter/seccomp_filter.cpp b/greeter/seccomp_filter.cpp
index 9d61d4a..a266331 100644
--- a/greeter/seccomp_filter.cpp
+++ b/greeter/seccomp_filter.cpp
@@ -78,6 +78,7 @@ void init()
         seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(open), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY));
         seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(open), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR));
     }
+    seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(openat), 1, SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT));
     seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(open), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT));
 
     // disallow going to a socket

Why this is now necessary with glibc 2.26 is not obvious, my guess is that glibc
rewrote openat(AT_FDCWD, "/...", ...) calls to open("/...", ...) or does it the
other way around now with 2.26.

This makes me wonder whether the seccomp sandbox actually works as intended.
AFAICT blocking openat is always necessary (?)

This could be confirmed by inserting a direct call to openat in the seccomp
test and running it on glibc < 2.26.
Comment 2 Fabian Vogt 2017-09-13 08:10:37 UTC
Just asked a glibc maintainer, it is intentional behaviour.
With version 2.26, glibc does not do any open syscalls anymore, but converts every open call to openat. The main reason is that newer platforms do not actually have a open syscall anymore.
This means that kscreenlocker's seccomp filter is actually ineffective for openat calls right now.
Comment 3 Martin Flöser 2017-09-13 16:09:17 UTC
Fabian, could you please push your patch?
Comment 4 Fabian Vogt 2017-09-13 16:17:45 UTC
(In reply to Martin Flöser from comment #3)
> Fabian, could you please push your patch?

I'm not quite sure whether it is complete, the open syscall is also referenced in the block above it. Would duplicating those lines for openat be correct?
Comment 5 Martin Flöser 2017-09-13 18:15:49 UTC
(In reply to Fabian Vogt from comment #4)
> (In reply to Martin Flöser from comment #3)
> > Fabian, could you please push your patch?
> 
> I'm not quite sure whether it is complete, the open syscall is also
> referenced in the block above it. Would duplicating those lines for openat
> be correct?

yep, would be correct. We need all three.
Comment 6 Fabian Vogt 2017-09-13 18:27:37 UTC
Git commit 1d70ac4096acbd7e68fb776086f66b70aebc3261 by Fabian Vogt.
Committed on 13/09/2017 at 18:27.
Pushed by fvogt into branch 'master'.

seccomp filter: Handle openat as well

Summary:
With glibc 2.26, the open syscall is not used anymore as openat is favored.
This causes the testcase to fail, which shows that openat is not handled
correctly by the seccomp filter.
This adds a testcase that tests both open and openat (needs to use direct
syscalls on glibc 2.26 as calls to open would otherwise result in openat)
and implements the proper handling for openat in the filter.

Test Plan:
Ran seccomp test before and after, now succeeds.
Ran make install, screenlocker still works.

Reviewers: #plasma, graesslin

Reviewed By: #plasma, graesslin

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D7806

M  +35   -0    greeter/autotests/seccomp_test.cpp
M  +3    -0    greeter/seccomp_filter.cpp

https://commits.kde.org/kscreenlocker/1d70ac4096acbd7e68fb776086f66b70aebc3261