[WK2] Drop WebProcess capabilities on Linux using seccomp filters

https://bugs.webkit.org/show_bug.cgi?id=89875

Reviewed by Maciej Stachowiak.

.:

Added the bits to EFL/CMake buildsystem to find the libseccomp
library.

* Source/cmake/FindLibSeccomp.cmake: Added.
* Source/cmake/OptionsEfl.cmake:
* Source/cmake/WebKitFeatures.cmake:
* Source/cmakeconfig.h.cmake:

Source/WebCore:

Make the DATA_DIR global since it is now needed for WebCore and WebKit2.
It is now used to set a sandbox policy for the EFL port.

* PlatformEfl.cmake:

Source/WebKit2:

Introduce the foundations of the SeccompFilter-based sandbox. The
hardening of the WebProcess (and potentially PluginProcess, etc)
works by a combination of the two things:

- Blocking syscalls that are not used, reducing the size of the attack
surface.
- Trapping sensitive syscalls and delegating the execution of these
syscalls to a separated trusted process subject to a set of policies.

The initial implementation traps the open()-family of syscalls on WebKit
EFL's and Qt's WebProcess, but it could be easily used by any Linux port,
since the code is suppose to be Linux-compliant. The list of syscalls handled
by the broker process should definitely grow as we mature the
implementation. Other syscalls needs to be handled to get this sandbox
fully functional, like unlink(), mkdir(), etc.

The broker process should be initialized as early as possible on the
sandboxed process main() function, because it only does a fork(), which
is cheap on Linux. That also aims to minimize the resident memory footprint
of the broker process.

Opening of files for upload and saving downloads is not supported yet,
since it should be handled to the UIProcess in a similar fashion as
the Mac port does.

* PlatformEfl.cmake:
* Shared/linux/SeccompFilters/OpenSyscall.cpp: Added.
(WebKit):
(WebKit::OpenSyscall::createFromOpenatContext):
(WebKit::OpenSyscall::createFromCreatContext):
(WebKit::OpenSyscall::OpenSyscall):
(WebKit::OpenSyscall::setResult):
(WebKit::OpenSyscall::execute):
(WebKit::OpenSyscall::encode):
(WebKit::OpenSyscall::decode):
(WebKit::OpenSyscallResult::OpenSyscallResult):
(WebKit::OpenSyscallResult::~OpenSyscallResult):
(WebKit::OpenSyscallResult::encode):
(WebKit::OpenSyscallResult::decode):
* Shared/linux/SeccompFilters/OpenSyscall.h: Added.
(CoreIPC):
(WebKit):
(OpenSyscall):
(WebKit::OpenSyscall::setPath):
(WebKit::OpenSyscall::setFlags):
(WebKit::OpenSyscall::setMode):
(OpenSyscallResult):
(WebKit::OpenSyscallResult::fd):
(WebKit::OpenSyscallResult::errorNumber):
* Shared/linux/SeccompFilters/SeccompBroker.cpp: Added.
(WebKit):
(SeccompBrokerClient):
(WebKit::sendMessage):
(WebKit::receiveMessage):
(WebKit::SIGSYSHandler):
(WebKit::registerSIGSYSHandler):
(WebKit::SeccompBrokerClient::shared):
(WebKit::SeccompBrokerClient::SeccompBrokerClient):
(WebKit::SeccompBrokerClient::~SeccompBrokerClient):
(WebKit::SeccompBrokerClient::dispatch):
(WebKit::SeccompBrokerClient::handleIfOpeningOnlineCPUCount):
(WebKit::SeccompBroker::launchProcess):
(WebKit::SeccompBroker::initialize):
(WebKit::SeccompBroker::runLoop):
* Shared/linux/SeccompFilters/SeccompBroker.h: Added.
(WebKit):
(SeccompBroker):
(WebKit::SeccompBroker::setSyscallPolicy):
(WebKit::SeccompBroker::SeccompBroker):
* Shared/linux/SeccompFilters/SeccompFilters.cpp: Added.
(WebKit):
(WebKit::SeccompFilters::SeccompFilters):
(WebKit::SeccompFilters::~SeccompFilters):
(WebKit::SeccompFilters::addRule):
(WebKit::SeccompFilters::initialize):
* Shared/linux/SeccompFilters/SeccompFilters.h: Added.
(WebKit):
(SeccompFilters):
(WebKit::SeccompFilters::context):
(WebKit::SeccompFilters::platformInitialize):
* Shared/linux/SeccompFilters/SigactionSyscall.cpp: Added.
(WebKit):
(WebKit::SigactionSyscall::createFromContext):
* Shared/linux/SeccompFilters/SigactionSyscall.h: Added.
(WebKit):
(SigactionSyscall):
* Shared/linux/SeccompFilters/SigprocmaskSyscall.cpp: Added.
(WebKit):
(WebKit::SigprocmaskSyscall::createFromContext):
* Shared/linux/SeccompFilters/SigprocmaskSyscall.h: Added.
(WebKit):
(SigprocmaskSyscall):
* Shared/linux/SeccompFilters/Syscall.cpp: Added.
(WebKit):
(WebKit::Syscall::createFromContext):
(WebKit::Syscall::createFromDecoder):
(WebKit::Syscall::Syscall):
(WebKit::SyscallResult::createFromDecoder):
(WebKit::SyscallResult::SyscallResult):
* Shared/linux/SeccompFilters/Syscall.h: Added.
(CoreIPC):
(WebKit):
(Syscall):
(WebKit::Syscall::~Syscall):
(WebKit::Syscall::type):
(WebKit::Syscall::setContext):
(WebKit::Syscall::context):
(SyscallResult):
(WebKit::SyscallResult::~SyscallResult):
(WebKit::SyscallResult::type):
* Shared/linux/SeccompFilters/SyscallPolicy.cpp: Added.
(WebKit):
(WebKit::removeTrailingSlash):
(WebKit::SyscallPolicy::hasPermissionForPath):
(WebKit::SyscallPolicy::addFilePermission):
(WebKit::SyscallPolicy::addDirectoryPermission):
(WebKit::SyscallPolicy::addDefaultWebProcessPolicy):
* Shared/linux/SeccompFilters/SyscallPolicy.h: Added.
(WebKit):
(SyscallPolicy):
* Target.pri:
* WebKit2.pri:
* WebProcess/efl/SeccompFiltersWebProcessEfl.cpp: Added.
(WebKit):
(WebKit::SeccompFiltersWebProcessEfl::SeccompFiltersWebProcessEfl):
(WebKit::SeccompFiltersWebProcessEfl::platformInitialize):
* WebProcess/efl/SeccompFiltersWebProcessEfl.h: Added.
(WebKit):
(SeccompFiltersWebProcessEfl):
* WebProcess/qt/SeccompFiltersWebProcessQt.cpp: Added.
(WebKit):
(WebKit::SeccompFiltersWebProcessQt::SeccompFiltersWebProcessQt):
(WebKit::SeccompFiltersWebProcessQt::platformInitialize):
* WebProcess/qt/SeccompFiltersWebProcessQt.h: Added.
(WebKit):
(SeccompFiltersWebProcessQt):
* WebProcess/qt/WebProcessQt.cpp:
(WebKit::WebProcess::platformInitializeWebProcess):
* WebProcess/soup/WebProcessSoup.cpp:
(WebKit::WebProcess::platformInitializeWebProcess):

Tools:

Add unit tests to verify if the handling of the open, openat, creat syscall
is being done right. We check if the Read/Write/ReadAndWrite permissions
are respected, if the canonical path is being resolved and if
the permissions are falling back to the topmost parent directory with a
policy set when the directory being opened has no policy.

We also test if any attempt of blocking SIGSYS is silently ignored.
SIGSYS cannot be blocked because in it's handler is where we hook
syscalls to the broker process.

Also added libseccomp to EFL's jhbuild to make the life of developers
willing to help easier.

* Scripts/webkitperl/FeatureList.pm:
* TestWebKitAPI/PlatformEfl.cmake:
* TestWebKitAPI/Tests/WebKit2/SeccompFilters.cpp: Added.
(TestWebKitAPI):
(SeccompEnvironment):
(TestWebKitAPI::SeccompEnvironment::SetUp):
(TestWebKitAPI::SeccompEnvironment::TearDown):
(TestWebKitAPI::dummyHandler):
(TestWebKitAPI::TEST):
(TestWebKitAPI::stressTest):
* efl/jhbuild.modules:
* qmake/mkspecs/features/features.pri:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@147998 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 1a35730e
2013-04-09 Thiago Marcos P. Santos <thiago.santos@intel.com>
[WK2] Drop WebProcess capabilities on Linux using seccomp filters
https://bugs.webkit.org/show_bug.cgi?id=89875
Reviewed by Maciej Stachowiak.
Added the bits to EFL/CMake buildsystem to find the libseccomp
library.
* Source/cmake/FindLibSeccomp.cmake: Added.
* Source/cmake/OptionsEfl.cmake:
* Source/cmake/WebKitFeatures.cmake:
* Source/cmakeconfig.h.cmake:
2013-04-09 Carlos Garcia Campos <cgarcia@igalia.com>
Unreviewed. Fix GTK+ 32 bit build.
......
2013-04-09 Thiago Marcos P. Santos <thiago.santos@intel.com>
[WK2] Drop WebProcess capabilities on Linux using seccomp filters
https://bugs.webkit.org/show_bug.cgi?id=89875
Reviewed by Maciej Stachowiak.
Make the DATA_DIR global since it is now needed for WebCore and WebKit2.
It is now used to set a sandbox policy for the EFL port.
* PlatformEfl.cmake:
2013-04-08 Ryosuke Niwa <rniwa@webkit.org>
Remove WebCore.gyp/gypi
......@@ -362,8 +362,6 @@ if (WTF_USE_3D_GRAPHICS)
endif ()
endif ()
add_definitions(-DDATA_DIR="${CMAKE_INSTALL_PREFIX}/${DATA_INSTALL_DIR}")
if (ENABLE_WEB_AUDIO)
list(APPEND WebCore_INCLUDE_DIRECTORIES
"${WEBCORE_DIR}/platform/audio/gstreamer"
......
2013-04-09 Thiago Marcos P. Santos <thiago.santos@intel.com>
[WK2] Drop WebProcess capabilities on Linux using seccomp filters
https://bugs.webkit.org/show_bug.cgi?id=89875
Reviewed by Maciej Stachowiak.
Introduce the foundations of the SeccompFilter-based sandbox. The
hardening of the WebProcess (and potentially PluginProcess, etc)
works by a combination of the two things:
- Blocking syscalls that are not used, reducing the size of the attack
surface.
- Trapping sensitive syscalls and delegating the execution of these
syscalls to a separated trusted process subject to a set of policies.
The initial implementation traps the open()-family of syscalls on WebKit
EFL's and Qt's WebProcess, but it could be easily used by any Linux port,
since the code is suppose to be Linux-compliant. The list of syscalls handled
by the broker process should definitely grow as we mature the
implementation. Other syscalls needs to be handled to get this sandbox
fully functional, like unlink(), mkdir(), etc.
The broker process should be initialized as early as possible on the
sandboxed process main() function, because it only does a fork(), which
is cheap on Linux. That also aims to minimize the resident memory footprint
of the broker process.
Opening of files for upload and saving downloads is not supported yet,
since it should be handled to the UIProcess in a similar fashion as
the Mac port does.
* PlatformEfl.cmake:
* Shared/linux/SeccompFilters/OpenSyscall.cpp: Added.
(WebKit):
(WebKit::OpenSyscall::createFromOpenatContext):
(WebKit::OpenSyscall::createFromCreatContext):
(WebKit::OpenSyscall::OpenSyscall):
(WebKit::OpenSyscall::setResult):
(WebKit::OpenSyscall::execute):
(WebKit::OpenSyscall::encode):
(WebKit::OpenSyscall::decode):
(WebKit::OpenSyscallResult::OpenSyscallResult):
(WebKit::OpenSyscallResult::~OpenSyscallResult):
(WebKit::OpenSyscallResult::encode):
(WebKit::OpenSyscallResult::decode):
* Shared/linux/SeccompFilters/OpenSyscall.h: Added.
(CoreIPC):
(WebKit):
(OpenSyscall):
(WebKit::OpenSyscall::setPath):
(WebKit::OpenSyscall::setFlags):
(WebKit::OpenSyscall::setMode):
(OpenSyscallResult):
(WebKit::OpenSyscallResult::fd):
(WebKit::OpenSyscallResult::errorNumber):
* Shared/linux/SeccompFilters/SeccompBroker.cpp: Added.
(WebKit):
(SeccompBrokerClient):
(WebKit::sendMessage):
(WebKit::receiveMessage):
(WebKit::SIGSYSHandler):
(WebKit::registerSIGSYSHandler):
(WebKit::SeccompBrokerClient::shared):
(WebKit::SeccompBrokerClient::SeccompBrokerClient):
(WebKit::SeccompBrokerClient::~SeccompBrokerClient):
(WebKit::SeccompBrokerClient::dispatch):
(WebKit::SeccompBrokerClient::handleIfOpeningOnlineCPUCount):
(WebKit::SeccompBroker::launchProcess):
(WebKit::SeccompBroker::initialize):
(WebKit::SeccompBroker::runLoop):
* Shared/linux/SeccompFilters/SeccompBroker.h: Added.
(WebKit):
(SeccompBroker):
(WebKit::SeccompBroker::setSyscallPolicy):
(WebKit::SeccompBroker::SeccompBroker):
* Shared/linux/SeccompFilters/SeccompFilters.cpp: Added.
(WebKit):
(WebKit::SeccompFilters::SeccompFilters):
(WebKit::SeccompFilters::~SeccompFilters):
(WebKit::SeccompFilters::addRule):
(WebKit::SeccompFilters::initialize):
* Shared/linux/SeccompFilters/SeccompFilters.h: Added.
(WebKit):
(SeccompFilters):
(WebKit::SeccompFilters::context):
(WebKit::SeccompFilters::platformInitialize):
* Shared/linux/SeccompFilters/SigactionSyscall.cpp: Added.
(WebKit):
(WebKit::SigactionSyscall::createFromContext):
* Shared/linux/SeccompFilters/SigactionSyscall.h: Added.
(WebKit):
(SigactionSyscall):
* Shared/linux/SeccompFilters/SigprocmaskSyscall.cpp: Added.
(WebKit):
(WebKit::SigprocmaskSyscall::createFromContext):
* Shared/linux/SeccompFilters/SigprocmaskSyscall.h: Added.
(WebKit):
(SigprocmaskSyscall):
* Shared/linux/SeccompFilters/Syscall.cpp: Added.
(WebKit):
(WebKit::Syscall::createFromContext):
(WebKit::Syscall::createFromDecoder):
(WebKit::Syscall::Syscall):
(WebKit::SyscallResult::createFromDecoder):
(WebKit::SyscallResult::SyscallResult):
* Shared/linux/SeccompFilters/Syscall.h: Added.
(CoreIPC):
(WebKit):
(Syscall):
(WebKit::Syscall::~Syscall):
(WebKit::Syscall::type):
(WebKit::Syscall::setContext):
(WebKit::Syscall::context):
(SyscallResult):
(WebKit::SyscallResult::~SyscallResult):
(WebKit::SyscallResult::type):
* Shared/linux/SeccompFilters/SyscallPolicy.cpp: Added.
(WebKit):
(WebKit::removeTrailingSlash):
(WebKit::SyscallPolicy::hasPermissionForPath):
(WebKit::SyscallPolicy::addFilePermission):
(WebKit::SyscallPolicy::addDirectoryPermission):
(WebKit::SyscallPolicy::addDefaultWebProcessPolicy):
* Shared/linux/SeccompFilters/SyscallPolicy.h: Added.
(WebKit):
(SyscallPolicy):
* Target.pri:
* WebKit2.pri:
* WebProcess/efl/SeccompFiltersWebProcessEfl.cpp: Added.
(WebKit):
(WebKit::SeccompFiltersWebProcessEfl::SeccompFiltersWebProcessEfl):
(WebKit::SeccompFiltersWebProcessEfl::platformInitialize):
* WebProcess/efl/SeccompFiltersWebProcessEfl.h: Added.
(WebKit):
(SeccompFiltersWebProcessEfl):
* WebProcess/qt/SeccompFiltersWebProcessQt.cpp: Added.
(WebKit):
(WebKit::SeccompFiltersWebProcessQt::SeccompFiltersWebProcessQt):
(WebKit::SeccompFiltersWebProcessQt::platformInitialize):
* WebProcess/qt/SeccompFiltersWebProcessQt.h: Added.
(WebKit):
(SeccompFiltersWebProcessQt):
* WebProcess/qt/WebProcessQt.cpp:
(WebKit::WebProcess::platformInitializeWebProcess):
* WebProcess/soup/WebProcessSoup.cpp:
(WebKit::WebProcess::platformInitializeWebProcess):
2013-04-08 Grzegorz Czajkowski <g.czajkowski@samsung.com>
[WK2][EFL] Mark not implemented methods in TextCheckerEfl.
......@@ -27,6 +27,14 @@ list(APPEND WebKit2_SOURCES
Shared/efl/ProcessExecutablePathEfl.cpp
Shared/efl/WebEventFactory.cpp
Shared/linux/SeccompFilters/OpenSyscall.cpp
Shared/linux/SeccompFilters/SigactionSyscall.cpp
Shared/linux/SeccompFilters/SigprocmaskSyscall.cpp
Shared/linux/SeccompFilters/SeccompBroker.cpp
Shared/linux/SeccompFilters/SeccompFilters.cpp
Shared/linux/SeccompFilters/Syscall.cpp
Shared/linux/SeccompFilters/SyscallPolicy.cpp
Shared/linux/WebMemorySamplerLinux.cpp
Shared/soup/PlatformCertificateInfo.cpp
......@@ -149,6 +157,7 @@ list(APPEND WebKit2_SOURCES
WebProcess/WebPage/efl/WebInspectorEfl.cpp
WebProcess/WebPage/efl/WebPageEfl.cpp
WebProcess/efl/SeccompFiltersWebProcessEfl.cpp
WebProcess/efl/WebProcessMainEfl.cpp
WebProcess/soup/WebProcessSoup.cpp
......@@ -255,6 +264,21 @@ list(APPEND WebProcess_LIBRARIES
${SQLITE_LIBRARIES}
)
if (ENABLE_SECCOMP_FILTERS)
list(APPEND WebKit2_LIBRARIES
${LIBSECCOMP_LIBRARIES}
)
list(APPEND WebKit2_INCLUDE_DIRECTORIES
${LIBSECCOMP_INCLUDE_DIRS}
)
# If building with jhbuild, add the root build directory to the
# filesystem access policy.
if (IS_DIRECTORY ${CMAKE_SOURCE_DIR}/WebKitBuild/Dependencies)
add_definitions(-DSOURCE_DIR=\"${CMAKE_SOURCE_DIR}\")
endif ()
endif ()
if (ENABLE_ECORE_X)
list(APPEND WebProcess_LIBRARIES
${ECORE_X_LIBRARIES}
......
/*
* Copyright (C) 2013 Intel Corporation. All rights reserved.
*
* 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 above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS CONTRIBUTORS
* 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.
*/
#include "config.h"
#include "OpenSyscall.h"
#if ENABLE(SECCOMP_FILTERS)
#include "ArgumentCoders.h"
#include "SyscallPolicy.h"
#include <errno.h>
#include <fcntl.h>
#include <seccomp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wtf/text/WTFString.h>
namespace WebKit {
COMPILE_ASSERT(!O_RDONLY, O_RDONLY);
COMPILE_ASSERT(O_WRONLY == 1, O_WRONLY);
COMPILE_ASSERT(O_RDWR == 2, O_RDWR);
PassOwnPtr<Syscall> OpenSyscall::createFromOpenatContext(mcontext_t* context)
{
OwnPtr<OpenSyscall> open = adoptPtr(new OpenSyscall(0));
open->setFlags(context->gregs[REG_ARG2]);
open->setMode(context->gregs[REG_ARG3]);
open->setContext(context);
int fd = context->gregs[REG_ARG0];
char* path = reinterpret_cast<char*>(context->gregs[REG_ARG1]);
if (path[0] == '/') {
open->setPath(path);
return open.release();
}
struct stat pathStat;
if (fstat(fd, &pathStat) == -1) {
context->gregs[REG_SYSCALL] = -errno;
return nullptr;
}
if (!S_ISDIR(pathStat.st_mode)) {
context->gregs[REG_SYSCALL] = -ENOTDIR;
return nullptr;
}
char fdLinkPath[32];
snprintf(fdLinkPath, sizeof(fdLinkPath), "/proc/self/fd/%d", fd);
char fdPath[PATH_MAX];
ssize_t size = readlink(fdLinkPath, fdPath, sizeof(fdPath) - 1);
if (size == -1) {
context->gregs[REG_SYSCALL] = -errno;
return nullptr;
}
// The "+ 2" here stands for the '/' and null terminator.
if (size + strlen(path) + 2 > PATH_MAX) {
context->gregs[REG_SYSCALL] = -ENAMETOOLONG;
return nullptr;
}
sprintf(&fdPath[size], "/%s", path);
open->setPath(fdPath);
return open.release();
}
PassOwnPtr<Syscall> OpenSyscall::createFromCreatContext(mcontext_t* context)
{
OpenSyscall* open = new OpenSyscall(0);
open->setPath(CString(reinterpret_cast<char*>(context->gregs[REG_ARG0])));
open->setFlags(O_CREAT | O_WRONLY | O_TRUNC);
open->setMode(context->gregs[REG_ARG1]);
open->setContext(context);
return adoptPtr(open);
}
OpenSyscall::OpenSyscall(mcontext_t* context)
: Syscall(__NR_open, context)
, m_flags(0)
, m_mode(0)
{
if (!context)
return;
m_path = CString(reinterpret_cast<char*>(context->gregs[REG_ARG0]));
m_flags = context->gregs[REG_ARG1];
m_mode = context->gregs[REG_ARG2];
}
void OpenSyscall::setResult(const SyscallResult* result)
{
ASSERT(context() && result->type() == type());
const OpenSyscallResult* openResult = static_cast<const OpenSyscallResult*>(result);
if (openResult->fd() >= 0)
context()->gregs[REG_SYSCALL] = dup(openResult->fd());
else
context()->gregs[REG_SYSCALL] = -openResult->errorNumber();
}
PassOwnPtr<SyscallResult> OpenSyscall::execute(const SyscallPolicy& policy)
{
if (!strncmp("/proc/self/", m_path.data(), 11)) {
String resolvedSelfPath = ASCIILiteral("/proc/") + String::number(getppid()) + &m_path.data()[10];
m_path = resolvedSelfPath.utf8().data();
}
SyscallPolicy::Permission permission = SyscallPolicy::NotAllowed;
if (m_flags & O_RDWR)
permission = static_cast<SyscallPolicy::Permission>(permission | SyscallPolicy::ReadAndWrite);
else if (m_flags & O_WRONLY)
permission = static_cast<SyscallPolicy::Permission>(permission | SyscallPolicy::Write);
else
permission = static_cast<SyscallPolicy::Permission>(permission | SyscallPolicy::Read);
// Create a file implies write permission on the directory.
if (m_flags & O_CREAT || m_flags & O_EXCL)
permission = static_cast<SyscallPolicy::Permission>(permission | SyscallPolicy::Write);
if (!policy.hasPermissionForPath(m_path.data(), permission))
return adoptPtr(new OpenSyscallResult(-1, EACCES));
// Permission granted, execute the syscall. The syscall might still
// fail because of hard permissions enforced by the filesystem and
// things like if the entry does not exist.
int fd = open(m_path.data(), m_flags, m_mode);
int errorNumber = fd == -1 ? errno : 0;
return adoptPtr(new OpenSyscallResult(fd, errorNumber));
}
void OpenSyscall::encode(CoreIPC::ArgumentEncoder& encoder) const
{
encoder << type();
encoder << m_path;
encoder << m_flags;
encoder << m_mode;
}
bool OpenSyscall::decode(CoreIPC::ArgumentDecoder* decoder)
{
// m_type already decoded by the parent class.
if (!decoder->decode(m_path))
return false;
if (!decoder->decode(m_flags))
return false;
return decoder->decode(m_mode);
}
OpenSyscallResult::OpenSyscallResult(int fd, int errorNumber)
: SyscallResult(__NR_open)
, m_fd(fd)
, m_errorNumber(errorNumber)
{
}
OpenSyscallResult::~OpenSyscallResult()
{
if (m_fd >= 0)
close(m_fd);
}
void OpenSyscallResult::encode(CoreIPC::ArgumentEncoder& encoder) const
{
encoder << type();
if (m_fd >= 0) {
CoreIPC::Attachment attachment(m_fd);
encoder.addAttachment(attachment);
}
encoder << m_errorNumber;
}
bool OpenSyscallResult::decode(CoreIPC::ArgumentDecoder* decoder, int fd)
{
if (fd >= 0)
m_fd = fd;
return decoder->decode(m_errorNumber);
}
} // namespace WebKit
#endif // ENABLE(SECCOMP_FILTERS)
/*
* Copyright (C) 2013 Intel Corporation. All rights reserved.
*
* 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 above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS CONTRIBUTORS
* 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.
*/
#ifndef OpenSyscall_h
#define OpenSyscall_h
#if ENABLE(SECCOMP_FILTERS)
#include "Syscall.h"
#include <wtf/text/CString.h>
namespace CoreIPC {
class ArgumentDecoder;
class ArgumentEncoder;
}
namespace WebKit {
class OpenSyscall : public Syscall {
public:
static PassOwnPtr<Syscall> createFromOpenatContext(mcontext_t*);
static PassOwnPtr<Syscall> createFromCreatContext(mcontext_t*);
explicit OpenSyscall(mcontext_t*);
void setPath(const CString& path) { m_path = path; };
void setFlags(const int flags) { m_flags = flags; };
void setMode(const mode_t mode) { m_mode = mode; };
// Syscall implementation.
virtual void setResult(const SyscallResult*);
virtual PassOwnPtr<SyscallResult> execute(const SyscallPolicy&);
virtual void encode(CoreIPC::ArgumentEncoder&) const;
virtual bool decode(CoreIPC::ArgumentDecoder*);
private:
CString m_path;
int m_flags;
mode_t m_mode;
};
class OpenSyscallResult : public SyscallResult {
public:
OpenSyscallResult(int fd, int errorNumber);
~OpenSyscallResult();
int fd() const { return m_fd; }
int errorNumber() const { return m_errorNumber; }
// SyscallResult implementation.
virtual void encode(CoreIPC::ArgumentEncoder&) const;
virtual bool decode(CoreIPC::ArgumentDecoder*, int fd);
private:
int m_fd;
int m_errorNumber;
};
} // namespace WebKit
#endif // ENABLE(SECCOMP_FILTERS)
#endif // OpenSyscall_h
This diff is collapsed.
/*
* Copyright (C) 2013 Intel Corporation. All rights reserved.
*
* 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 above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS CONTRIBUTORS
* 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.
*/
#ifndef SeccompBroker_h
#define SeccompBroker_h
#if ENABLE(SECCOMP_FILTERS)
#include "SeccompFilters.h"
#include "Syscall.h"
#include "SyscallPolicy.h"
#include <signal.h>
#include <wtf/Noncopyable.h>
#include <wtf/Threading.h>
#include <wtf/Vector.h>
namespace WebKit {
class SeccompBroker {
WTF_MAKE_NONCOPYABLE(SeccompBroker);
public:
static void launchProcess(SeccompFilters*, const SyscallPolicy&);
void initialize();
void setSyscallPolicy(const SyscallPolicy& policy) { m_policy = policy; }
private:
SeccompBroker() { }
void runLoop(int socket);
SyscallPolicy m_policy;
};
} // namespace WebKit
#endif // ENABLE(SECCOMP_FILTERS)
#endif // SeccompBroker_h
/*
* Copyright (C) 2013 Intel Corporation. All rights reserved.
*
* 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 above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``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 APPLE INC. OR ITS CONTRIBUTORS
* 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.
*/
#include "config.h"
#include "SeccompFilters.h"
#if ENABLE(SECCOMP_FILTERS)
#include "SeccompBroker.h"
#include <seccomp.h>
#include <wtf/Assertions.h>
namespace WebKit {
COMPILE_ASSERT(SeccompFilters::Allow == SCMP_ACT_ALLOW, Allow);
COMPILE_ASSERT(SeccompFilters::Kill == SCMP_ACT_KILL, Kill);
COMPILE_ASSERT(SeccompFilters::Trap == SCMP_ACT_TRAP, Trap);
COMPILE_ASSERT(SeccompFilters::NotSet == static_cast<SeccompFilters::Operator>(_SCMP_CMP_MIN), NotSet);
COMPILE_ASSERT(SeccompFilters::NotEqual == static_cast<SeccompFilters::Operator>(SCMP_CMP_NE), NotEqual);
COMPILE_ASSERT(SeccompFilters::Equal == static_cast<SeccompFilters::Operator>(SCMP_CMP_EQ), Equal);
COMPILE_ASSERT(sizeof(scmp_datum_t) == sizeof(long long), scmp_datum_t);
SeccompFilters::SeccompFilters(Action defaultAction)
: m_context(seccomp_init(defaultAction))
, m_initialized(false)
{
if (!m_context)
CRASH();
}
SeccompFilters::~SeccompFilters()
{
seccomp_release(m_context);
}
void SeccompFilters::addRule(const char* syscallName, Action action,
unsigned argNum1, Operator operator1, long long data1,
unsigned argNum2, Operator operator2, long long data2)
{
int syscall = seccomp_syscall_resolve_name(syscallName);
if (syscall == __NR_SCMP_ERROR)
CRASH();
int result;
if (operator2 != NotSet)
result = seccomp_rule_add(m_context, action, syscall, 2,
SCMP_CMP(argNum1, static_cast<scmp_compare>(operator1), data1, 0),
SCMP_CMP(argNum2, static_cast<scmp_compare>(operator2), data2, 0));
else if (operator1 != NotSet)
result = seccomp_rule_add(m_context, action, syscall, 1,
SCMP_CMP(argNum1, static_cast<scmp_compare>(operator1), data1, 0));
else
result = seccomp_rule_add(m_context, action, syscall, 0);
if (result < 0)
CRASH();
}
void SeccompFilters::initialize()
{
if (m_initialized)
return;
// Implement this is not required in case we are just
// setting filters. This is a good place to create the
// broker and syscall policy otherwise.
platformInitialize();