diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,16 @@ include_directories(${LMDB_INCLUDE_DIRS}) endif() +find_package(Seccomp) +set_package_properties(Seccomp PROPERTIES + TYPE + OPTIONAL + PURPOSE + "Used for putting the file extractor into a sandbox." +) +set(HAVE_SECCOMP ${Seccomp_FOUND}) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) + # compiler flags and build system add_definitions(-DQT_NO_KEYWORDS) remove_definitions(-DQT_NO_CAST_FROM_ASCII) diff --git a/cmake/FindSeccomp.cmake b/cmake/FindSeccomp.cmake new file mode 100644 --- /dev/null +++ b/cmake/FindSeccomp.cmake @@ -0,0 +1,90 @@ +#.rst: +# FindSeccomp +# ----------- +# +# Try to locate the libseccomp library. +# If found, this will define the following variables: +# +# ``Seccomp_FOUND`` +# True if the seccomp library is available +# ``Seccomp_INCLUDE_DIRS`` +# The seccomp include directories +# ``Seccomp_LIBRARIES`` +# The seccomp libraries for linking +# +# If ``Seccomp_FOUND`` is TRUE, it will also define the following +# imported target: +# +# ``Seccomp::Seccomp`` +# The Seccomp library +# +# Since 5.44.0. + +#============================================================================= +# Copyright (c) 2017 Martin Flöser +# Copyright (c) 2017 David Kahles +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +find_package(PkgConfig QUIET) +pkg_check_modules(PKG_Libseccomp QUIET libseccomp) + +find_path(Seccomp_INCLUDE_DIRS + NAMES + seccomp.h + HINTS + ${PKG_Libseccomp_INCLUDE_DIRS} +) +find_library(Seccomp_LIBRARIES + NAMES + seccomp + HINTS + ${PKG_Libseccomp_LIBRARY_DIRS} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Seccomp + FOUND_VAR + Seccomp_FOUND + REQUIRED_VARS + Seccomp_LIBRARIES + Seccomp_INCLUDE_DIRS +) + +if (Seccomp_FOUND AND NOT TARGET Seccomp::Seccomp) + add_library(Seccomp::Seccomp UNKNOWN IMPORTED) + set_target_properties(Seccomp::Seccomp PROPERTIES + IMPORTED_LOCATION "${Seccomp_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${Seccomp_INCLUDE_DIRS}" + ) +endif() + +mark_as_advanced(Seccomp_LIBRARIES Seccomp_INCLUDE_DIRS) + +include(FeatureSummary) +set_package_properties(Seccomp PROPERTIES + URL "https://github.com/seccomp/libseccomp" + DESCRIPTION "The enhanced seccomp library." +) diff --git a/config.h.cmake b/config.h.cmake --- a/config.h.cmake +++ b/config.h.cmake @@ -0,0 +1,3 @@ +/* Whether seccomp is available */ +#cmakedefine01 HAVE_SECCOMP +#define FILE_EXTRACTOR_BIN "${CMAKE_BINARY_DIR}/bin/baloo_file_extractor" diff --git a/src/file/extractor/CMakeLists.txt b/src/file/extractor/CMakeLists.txt --- a/src/file/extractor/CMakeLists.txt +++ b/src/file/extractor/CMakeLists.txt @@ -16,6 +16,10 @@ ../baloodebug.cpp ) +if(HAVE_SECCOMP) + set(EXTRACTOR_SRCS ${EXTRACTOR_SRCS} seccomp_filter.cpp) +endif() + add_executable(baloo_file_extractor ${EXTRACTOR_SRCS}) target_compile_definitions(baloo_file_extractor PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}") @@ -31,6 +35,10 @@ KF5::IdleTime ) +if(HAVE_SECCOMP) + target_link_libraries(baloo_file_extractor Seccomp::Seccomp) +endif() + install(TARGETS baloo_file_extractor DESTINATION ${BIN_INSTALL_DIR}) if(BUILD_TESTING) diff --git a/src/file/extractor/app.h b/src/file/extractor/app.h --- a/src/file/extractor/app.h +++ b/src/file/extractor/app.h @@ -32,14 +32,14 @@ #include -#include "database.h" #include "../fileindexerconfig.h" #include "iohandler.h" #include "idlestatemonitor.h" namespace Baloo { class Transaction; +class Database; class App : public QObject { @@ -68,6 +68,7 @@ QStringList m_updatedFiles; Transaction* m_tr; + Database *db; }; } diff --git a/src/file/extractor/app.cpp b/src/file/extractor/app.cpp --- a/src/file/extractor/app.cpp +++ b/src/file/extractor/app.cpp @@ -25,6 +25,7 @@ #include "result.h" #include "idutils.h" #include "transaction.h" +#include "database.h" #include "baloodebug.h" #include "global.h" @@ -49,17 +50,18 @@ , m_io(STDIN_FILENO) , m_tr(nullptr) { + db = globalDatabaseInstance(); + if (!db->open(Database::ReadWriteDatabase)) { + qCritical() << "Failed to open the database"; + exit(1); + } else + qDebug() << "Database opened"; connect(&m_notifyNewData, &QSocketNotifier::activated, this, &App::slotNewInput); } void App::slotNewInput() { - Database *db = globalDatabaseInstance(); - if (!db->open(Database::ReadWriteDatabase)) { - qCritical() << "Failed to open the database"; - exit(1); - } - + Q_ASSERT(db->isOpen()); Q_ASSERT(m_tr == nullptr); m_tr = new Transaction(db, Transaction::ReadWrite); diff --git a/src/file/extractor/autotests/CMakeLists.txt b/src/file/extractor/autotests/CMakeLists.txt --- a/src/file/extractor/autotests/CMakeLists.txt +++ b/src/file/extractor/autotests/CMakeLists.txt @@ -7,3 +7,14 @@ TEST_NAME "extractorIOTest" LINK_LIBRARIES Qt5::Core Qt5::Test ) + +set(SECCOMP_TEST_SRC + seccomp_test.cpp + ../seccomp_filter.cpp +) +if(HAVE_SECCOMP) + ecm_add_test(${SECCOMP_TEST_SRC} + TEST_NAME "SeccompTest" + LINK_LIBRARIES Qt5::Core Qt5::DBus Qt5::Test Qt5::Network Seccomp::Seccomp + ) +endif() diff --git a/src/file/extractor/autotests/seccomp_test.cpp b/src/file/extractor/autotests/seccomp_test.cpp new file mode 100644 --- /dev/null +++ b/src/file/extractor/autotests/seccomp_test.cpp @@ -0,0 +1,205 @@ +/* + * This file is part of the KDE Baloo Project + * Copyright (C) 2017 David Kahles , Martin Flöser + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#include "../seccomp_filter.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#ifdef __linux__ +#include +#endif + +#if !defined(SYS_open) || !defined(SYS_openat) || !defined(SYS_creat) || !defined(SYS_truncate) \ + || !defined(SYS_rename) || !defined(SYS_renameat) || !defined(SYS_renameat2) || !defined(SYS_mkdir) \ + || !defined(SYS_mkdirat) || !defined(SYS_rmdir) || !defined(SYS_link) || !defined(SYS_linkat) \ + || !defined(SYS_unlink) || !defined(SYS_unlinkat) || !defined(SYS_symlink) || !defined(SYS_symlinkat) \ + || !defined(SYS_mknod) || !defined(SYS_mknodat) || !defined(SYS_chmod) || !defined(SYS_fchmod) \ + || !defined(SYS_fchmodat) || !defined(SYS_open_by_handle_at) +#error "Some systemcalls are not available, though seccomp is available." +#endif + +namespace Baloo { +class SeccompTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void testOpen(); + void testRename(); + void testTruncate(); + void testMkdir(); + void testRmdir(); + void testLinkUnlink(); + void testSymlink(); + void testMknod(); + void testChmod(); + void testNetworkAccess_data(); + void testNetworkAccess(); +private: + QLatin1Literal existingFile = QLatin1Literal(FILE_EXTRACTOR_BIN); + QLatin1Literal createPath = QLatin1Literal(FILE_EXTRACTOR_BIN ".new"); + QLatin1Literal existingDir = QLatin1Literal(FILE_EXTRACTOR_BIN ".newDir"); + const char* existingFileChar; + const char* createPathChar; +}; +} + +using namespace Baloo; + +void SeccompTest::initTestCase() +{ + qunsetenv("BALOO_SECCOMP_DISABLE"); + existingFileChar = existingFile.data(); + createPathChar = createPath.data(); + QDir::current().mkdir(existingDir); + SecComp::init(); +} + +/* + * We test the QT methods as well as the raw syscalls. The syscalls are tested because + * we can't rely on QT using a specific syscall. The QT methods are only used as an addional test. + */ + +void SeccompTest::testOpen() +{ + QFile file(existingFile); + QVERIFY(!file.open(QIODevice::ReadWrite)); + QVERIFY(!file.open(QIODevice::WriteOnly)); + + QVERIFY(syscall(SYS_open, existingFileChar, O_RDWR) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_open, existingFileChar, O_WRONLY) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_open, createPathChar, O_RDONLY | O_CREAT) == -1 && errno == EPERM); + + QVERIFY(syscall(SYS_openat, AT_FDCWD, existingFileChar, O_RDWR) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_openat, AT_FDCWD, existingFileChar, O_WRONLY) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_openat, AT_FDCWD, createPathChar, O_RDONLY | O_CREAT) == -1 && errno == EPERM); + + QVERIFY(syscall(SYS_creat, createPathChar, S_IRWXU) == -1 && errno == EPERM); +} + +void SeccompTest::testTruncate() +{ + QVERIFY(!QFile::resize(existingFile, 0)); + + QVERIFY(syscall(SYS_rename, existingFileChar, 0) == -1 && errno == EPERM); +} + +void SeccompTest::testRename() +{ + QVERIFY(!QFile::rename(existingFile, createPath)); + + QVERIFY(syscall(SYS_rename, existingFileChar, createPathChar) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_renameat, AT_FDCWD, existingFileChar, AT_FDCWD, createPathChar) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_renameat2, AT_FDCWD, existingFileChar, AT_FDCWD, createPathChar, 0) == -1 && errno == EPERM); +} + +void SeccompTest::testMkdir() +{ + QVERIFY(!QDir::current().mkdir(createPath)); + + QVERIFY(syscall(SYS_mkdir, createPathChar, S_IRWXU) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_mkdirat, AT_FDCWD, createPathChar, S_IRWXU) == -1 && errno == EPERM); +} + +void SeccompTest::testRmdir() +{ + QVERIFY(!QDir::current().remove(existingDir)); + + QVERIFY(syscall(SYS_rmdir, existingDir.data()) == -1 && errno == EPERM); +} + +void SeccompTest::testLinkUnlink() +{ + QVERIFY(!QFile::remove(existingFile)); + + QVERIFY(syscall(SYS_link, existingFileChar, createPathChar) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_link, AT_FDCWD, existingFileChar, AT_FDCWD, createPathChar) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_unlink, existingFileChar) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_link, AT_FDCWD, existingFileChar) == -1 && errno == EPERM); +} + +void SeccompTest::testSymlink() +{ + QVERIFY(!QFile::link(existingFile, createPath)); + + QVERIFY(syscall(SYS_link, existingFileChar, createPathChar) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_link, existingFileChar, AT_FDCWD, createPathChar) == -1 && errno == EPERM); +} + +void SeccompTest::testMknod() +{ + QVERIFY(syscall(SYS_mknod, createPathChar, S_IRWXU, S_IFIFO) == -1 && errno == EPERM); + QVERIFY(syscall(SYS_mknod, AT_FDCWD, createPathChar, S_IRWXU, S_IFIFO) == -1 && errno == EPERM); +} + +void SeccompTest::testChmod() +{ + QVERIFY(!QFile::setPermissions(existingFileChar, QFileDevice::ExeOwner)); + QVERIFY(syscall(SYS_chmod, existingFileChar, S_IRWXU) == -1 && errno == EPERM); + QFile file(existingFile); + QVERIFY(file.open(QIODevice::ReadOnly)); + QVERIFY(syscall(SYS_fchmod, file.handle(), S_IRWXU) == -1 && errno == EPERM); + file.close(); + QVERIFY(syscall(SYS_chmod, AT_FDCWD, existingFileChar, S_IRWXU, 0) == -1 && errno == EPERM); +} + +void SeccompTest::testNetworkAccess_data() +{ + QTest::addColumn("urlString"); + + QTest::newRow("domain") << QStringLiteral("https://www.kde.org"); + QTest::newRow("ip4") << QStringLiteral("http://91.189.93.5"); + // phabricator.kde.org + QTest::newRow("ip6") << QStringLiteral("http://[2a01:4f8:171:2687::4]/"); +} + +void SeccompTest::testNetworkAccess() +{ + QNetworkAccessManager manager; + QFETCH(QString, urlString); + QUrl url(urlString); + QNetworkRequest request(url); + auto reply = manager.get(request); + QVERIFY(reply); + QSignalSpy finishedSpy(reply, static_cast(&QNetworkReply::error)); + QVERIFY(finishedSpy.isValid()); + QVERIFY(finishedSpy.wait()); + QVERIFY(reply->error() != QNetworkReply::NoError); +} + +QTEST_MAIN(SeccompTest) +#include "seccomp_test.moc" diff --git a/src/file/extractor/main.cpp b/src/file/extractor/main.cpp --- a/src/file/extractor/main.cpp +++ b/src/file/extractor/main.cpp @@ -23,6 +23,11 @@ #include "app.h" #include "../priority.h" +#include +#if HAVE_SECCOMP +#include "seccomp_filter.h" +#endif + #include #include #include @@ -54,5 +59,11 @@ QObject::connect(&app, &QGuiApplication::saveStateRequest, disableSessionManagement); Baloo::App appObject; + + // init the sandbox +#if HAVE_SECCOMP + SecComp::init(); +#endif + return app.exec(); } diff --git a/src/file/extractor/seccomp_filter.h b/src/file/extractor/seccomp_filter.h new file mode 100644 --- /dev/null +++ b/src/file/extractor/seccomp_filter.h @@ -0,0 +1,33 @@ +/* + * This file is part of the KDE Baloo Project + * Copyright (C) 2017 Martin Flöser + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#ifndef EXTRACTOR_SECCOMP_FILTER_H +#define EXTRACTOR_SECCOMP_FILTER_H + +namespace SecComp +{ + +void init(); + +} + +#endif diff --git a/src/file/extractor/seccomp_filter.cpp b/src/file/extractor/seccomp_filter.cpp new file mode 100644 --- /dev/null +++ b/src/file/extractor/seccomp_filter.cpp @@ -0,0 +1,102 @@ +/* + * This file is part of the KDE Baloo Project + * Copyright (C) 2017 David Kahles , Martin Flöser + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + */ + +#include "seccomp_filter.h" + +#include +#include +#include + +#include +#include +#include +#include + +namespace SecComp +{ + +void init() +{ + if(qEnvironmentVariableIsSet("BALOO_SECCOMP_DISABLE")) { + return; + } + // access DBus to have the socket open + QDBusConnection::sessionBus(); + + // default action: allow, because we don't know what third party extractors will do, and want to confine them as little as possible + auto context = seccomp_init(SCMP_ACT_ALLOW); + if (!context) { + qWarning() << "Seccomp sandbox initialization failed"; + return; + } + + // Disallow all syscalls an attacker could use to modify the users filecontent or filename, or place a script in .config/autostart + 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(open), 1, SCMP_A1(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT)); + 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(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(creat), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(truncate), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(rename), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(renameat), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(renameat2), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mkdir), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mkdirat), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(rmdir), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(link), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(linkat), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(unlink), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(unlinkat), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(symlink), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(symlinkat), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mknod), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mknodat), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(chmod), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmod), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fchmodat), 0); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(open_by_handle_at), 1, SCMP_A2(SCMP_CMP_MASKED_EQ, O_WRONLY, O_WRONLY)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(open_by_handle_at), 1, SCMP_A2(SCMP_CMP_MASKED_EQ, O_RDWR, O_RDWR)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(open_by_handle_at), 1, SCMP_A2(SCMP_CMP_MASKED_EQ, O_CREAT, O_CREAT)); + + // Disallow internet access + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_INET, AF_INET)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_INET6, AF_INET6)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_IPX, AF_IPX)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_NETLINK, AF_NETLINK)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_X25, AF_X25)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_AX25, AF_AX25)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_ATMPVC, AF_ATMPVC)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_APPLETALK, AF_APPLETALK)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_PACKET, AF_PACKET)); + seccomp_rule_add(context, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_MASKED_EQ, AF_ALG, AF_ALG)); + + // and activate our rules + if (seccomp_load(context)) { + qWarning() << "Seccomp sandbox initialization failed"; + } + seccomp_release(context); +} + +} +