diff --git a/greeter/autotests/seccomp_test.cpp b/greeter/autotests/seccomp_test.cpp --- a/greeter/autotests/seccomp_test.cpp +++ b/greeter/autotests/seccomp_test.cpp @@ -29,6 +29,12 @@ #include #include +#ifdef __linux__ +#include +#endif +#include +#include +#include #include class SeccompTest : public QObject @@ -38,6 +44,8 @@ void initTestCase(); void testCreateFile(); void testOpenFile(); + void testOpenFilePosix(); + void testWriteFilePosix(); void testStartProcess(); void testNetworkAccess_data(); void testNetworkAccess(); @@ -66,6 +74,33 @@ QVERIFY(file.open(QIODevice::ReadOnly)); } +void SeccompTest::testOpenFilePosix() +{ + QVERIFY(open("/dev/null", O_RDONLY | O_CREAT, 0) == -1 && errno == EPERM); + QVERIFY(openat(AT_FDCWD, "/dev/null", O_RDONLY | O_CREAT, 0) == -1 && errno == EPERM); +#ifdef SYS_open + QVERIFY(syscall(SYS_open, "/dev/null", O_RDONLY | O_CREAT, 0) == -1 && errno == EPERM); +#endif +#ifdef SYS_openat + QVERIFY(syscall(SYS_openat, AT_FDCWD, "/dev/null", O_RDONLY | O_CREAT, 0) == -1 && errno == EPERM); +#endif +} + +void SeccompTest::testWriteFilePosix() +{ + if (KWin::GLPlatform::instance()->driver() == KWin::Driver_NVidia) { + QSKIP("Write protection not supported on NVIDIA"); + } + QVERIFY(open("/dev/null", O_RDWR) == -1 && errno == EPERM); + QVERIFY(openat(AT_FDCWD, "/dev/null", O_RDWR) == -1 && errno == EPERM); +#ifdef SYS_open + QVERIFY(syscall(SYS_open, "/dev/null", O_RDWR) == -1 && errno == EPERM); +#endif +#ifdef SYS_openat + QVERIFY(syscall(SYS_openat, AT_FDCWD, "/dev/null", O_RDWR) == -1 && errno == EPERM); +#endif +} + void SeccompTest::testStartProcess() { // QProcess fails already using pipe diff --git a/greeter/seccomp_filter.cpp b/greeter/seccomp_filter.cpp --- a/greeter/seccomp_filter.cpp +++ b/greeter/seccomp_filter.cpp @@ -76,8 +76,11 @@ // they should fail with EPERM error if (writeSupported) { 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(openat), 1, SCMP_A2(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_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