diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /security/sandbox/linux/reporter | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | security/sandbox/linux/reporter/SandboxReporter.cpp | 299 | ||||
-rw-r--r-- | security/sandbox/linux/reporter/SandboxReporter.h | 86 | ||||
-rw-r--r-- | security/sandbox/linux/reporter/SandboxReporterCommon.h | 66 | ||||
-rw-r--r-- | security/sandbox/linux/reporter/SandboxReporterWrappers.cpp | 199 | ||||
-rw-r--r-- | security/sandbox/linux/reporter/components.conf | 13 | ||||
-rw-r--r-- | security/sandbox/linux/reporter/moz.build | 36 |
6 files changed, 699 insertions, 0 deletions
diff --git a/security/sandbox/linux/reporter/SandboxReporter.cpp b/security/sandbox/linux/reporter/SandboxReporter.cpp new file mode 100644 index 0000000000..a7c71cd5c9 --- /dev/null +++ b/security/sandbox/linux/reporter/SandboxReporter.cpp @@ -0,0 +1,299 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "SandboxReporter.h" +#include "SandboxLogging.h" + +#include <algorithm> +#include <errno.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <time.h> // for clockid_t + +#include "GeckoProfiler.h" +#include "mozilla/Assertions.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/StaticMutex.h" +#include "mozilla/PodOperations.h" +#include "nsThreadUtils.h" +#include "mozilla/Telemetry.h" +#include "sandbox/linux/system_headers/linux_syscalls.h" + +// Distinguish architectures for the telemetry key. +#if defined(__i386__) +# define SANDBOX_ARCH_NAME "x86" +#elif defined(__x86_64__) +# define SANDBOX_ARCH_NAME "amd64" +#elif defined(__arm__) +# define SANDBOX_ARCH_NAME "arm" +#elif defined(__aarch64__) +# define SANDBOX_ARCH_NAME "arm64" +#else +# error "unrecognized architecture" +#endif + +namespace mozilla { + +StaticAutoPtr<SandboxReporter> SandboxReporter::sSingleton; + +SandboxReporter::SandboxReporter() + : mClientFd(-1), + mServerFd(-1), + mMutex("SandboxReporter"), + mBuffer(MakeUnique<SandboxReport[]>(kSandboxReporterBufferSize)), + mCount(0) {} + +bool SandboxReporter::Init() { + int fds[2]; + + if (0 != socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, fds)) { + SANDBOX_LOG_ERRNO("SandboxReporter: socketpair failed"); + return false; + } + mClientFd = fds[0]; + mServerFd = fds[1]; + + if (!PlatformThread::Create(0, this, &mThread)) { + SANDBOX_LOG_ERRNO("SandboxReporter: thread creation failed"); + close(mClientFd); + close(mServerFd); + mClientFd = mServerFd = -1; + return false; + } + + return true; +} + +SandboxReporter::~SandboxReporter() { + if (mServerFd < 0) { + return; + } + shutdown(mServerFd, SHUT_RD); + PlatformThread::Join(mThread); + close(mServerFd); + close(mClientFd); +} + +/* static */ +SandboxReporter* SandboxReporter::Singleton() { + static StaticMutex sMutex MOZ_UNANNOTATED; + StaticMutexAutoLock lock(sMutex); + + if (sSingleton == nullptr) { + sSingleton = new SandboxReporter(); + if (!sSingleton->Init()) { + // If socketpair or thread creation failed, trying to continue + // with child process creation is unlikely to succeed; crash + // instead of trying to handle that case. + MOZ_CRASH("SandboxRepoter::Singleton: initialization failed"); + } + // ClearOnShutdown must be called on the main thread and will + // destroy the object on the main thread. That *should* be safe; + // the destructor will shut down the reporter's socket reader + // thread before freeing anything, IPC should already be shut down + // by that point (so it won't race by calling Singleton()), all + // non-main XPCOM threads will also be shut down, and currently + // the only other user is the main-thread-only Troubleshoot.sys.mjs. + NS_DispatchToMainThread(NS_NewRunnableFunction( + "SandboxReporter::Singleton", [] { ClearOnShutdown(&sSingleton); })); + } + return sSingleton.get(); +} + +void SandboxReporter::GetClientFileDescriptorMapping(int* aSrcFd, + int* aDstFd) const { + MOZ_ASSERT(mClientFd >= 0); + *aSrcFd = mClientFd; + *aDstFd = kSandboxReporterFileDesc; +} + +// This function is mentioned in Histograms.json; keep that in mind if +// it's renamed or moved to a different file. +static void SubmitToTelemetry(const SandboxReport& aReport) { + nsAutoCString key; + // The key contains the process type, something that uniquely + // identifies the syscall, and in some cases arguments (see below + // for details). Arbitrary formatting choice: fields in the key are + // separated by ':', except that (arch, syscall#) pairs are + // separated by '/'. + // + // Examples: + // * "content:x86/64" (bug 1285768) + // * "content:x86_64/110" (bug 1285768) + // * "gmp:madvise:8" (bug 1303813) + // * "content:clock_gettime:4" (bug 1334687) + + switch (aReport.mProcType) { + case SandboxReport::ProcType::CONTENT: + key.AppendLiteral("content"); + break; + case SandboxReport::ProcType::FILE: + key.AppendLiteral("file"); + break; + case SandboxReport::ProcType::MEDIA_PLUGIN: + key.AppendLiteral("gmp"); + break; + case SandboxReport::ProcType::RDD: + key.AppendLiteral("rdd"); + break; + case SandboxReport::ProcType::SOCKET_PROCESS: + key.AppendLiteral("socket"); + break; + case SandboxReport::ProcType::UTILITY: + key.AppendLiteral("utility"); + break; + default: + MOZ_ASSERT(false); + } + key.Append(':'); + + switch (aReport.mSyscall) { + // Syscalls that are filtered by arguments in one or more of the + // policies in SandboxFilter.cpp should generally have those + // arguments included here, but don't include irrelevant + // information that would cause large numbers of distinct keys for + // the same issue -- for example, pids or pointers. When in + // doubt, include arguments only if they would typically be + // constants (or asm immediates) in the code making the syscall. + // + // Also, keep in mind that this is opt-out data collection and + // privacy is critical. While it's unlikely that information in + // the register values alone could personally identify a user + // (see also crash reports, where register contents are public), + // and the guidelines in the previous paragraph should rule out + // any value that's capable of holding PII, please be careful. + // + // When making changes here, please consult with a data steward + // (https://wiki.mozilla.org/Firefox/Data_Collection) and ask for + // a review if you are unsure about anything. + + // This macro includes one argument as a decimal number; it should + // be enough for most cases. +#define ARG_DECIMAL(name, idx) \ + case __NR_##name: \ + key.AppendLiteral(#name ":"); \ + key.AppendInt(aReport.mArgs[idx]); \ + break + + // This may be more convenient if the argument is a set of bit flags. +#define ARG_HEX(name, idx) \ + case __NR_##name: \ + key.AppendLiteral(#name ":0x"); \ + key.AppendInt(aReport.mArgs[idx], 16); \ + break + + // clockid_t is annoying: there are a small set of fixed timers, + // but it can also encode a pid/tid (or a fd for a hardware clock + // device); in this case the value is negative. +#define ARG_CLOCKID(name, idx) \ + case __NR_##name: \ + key.AppendLiteral(#name ":"); \ + if (static_cast<clockid_t>(aReport.mArgs[idx]) < 0) { \ + key.AppendLiteral("dynamic"); \ + } else { \ + key.AppendInt(aReport.mArgs[idx]); \ + } \ + break + + // The syscalls handled specially: + + ARG_HEX(clone, 0); // flags + ARG_DECIMAL(prctl, 0); // option + ARG_HEX(ioctl, 1); // request + ARG_DECIMAL(fcntl, 1); // cmd + ARG_DECIMAL(madvise, 2); // advice + ARG_CLOCKID(clock_gettime, 0); // clk_id + +#ifdef __NR_socketcall + ARG_DECIMAL(socketcall, 0); // call +#endif +#ifdef __NR_ipc + ARG_DECIMAL(ipc, 0); // call +#endif + +#undef ARG_DECIMAL +#undef ARG_HEX +#undef ARG_CLOCKID + + default: + // Otherwise just use the number, with the arch name to disambiguate. + key.Append(SANDBOX_ARCH_NAME "/"); + key.AppendInt(aReport.mSyscall); + } + + Telemetry::Accumulate(Telemetry::SANDBOX_REJECTED_SYSCALLS, key); +} + +void SandboxReporter::AddOne(const SandboxReport& aReport) { + SubmitToTelemetry(aReport); + + MutexAutoLock lock(mMutex); + mBuffer[mCount % kSandboxReporterBufferSize] = aReport; + ++mCount; +} + +void SandboxReporter::ThreadMain(void) { + // Create a nsThread wrapper for the current platform thread, and register it + // with the thread manager. + (void)NS_GetCurrentThread(); + + PlatformThread::SetName("SandboxReporter"); + AUTO_PROFILER_REGISTER_THREAD("SandboxReporter"); + + for (;;) { + SandboxReport rep; + struct iovec iov; + struct msghdr msg; + + iov.iov_base = &rep; + iov.iov_len = sizeof(rep); + PodZero(&msg); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + + const auto recvd = recvmsg(mServerFd, &msg, 0); + if (recvd < 0) { + if (errno == EINTR) { + continue; + } + SANDBOX_LOG_ERRNO("SandboxReporter: recvmsg"); + } + if (recvd <= 0) { + break; + } + + if (static_cast<size_t>(recvd) < sizeof(rep)) { + SANDBOX_LOG("SandboxReporter: packet too short (%d < %d)", recvd, + sizeof(rep)); + continue; + } + if (msg.msg_flags & MSG_TRUNC) { + SANDBOX_LOG("SandboxReporter: packet too long"); + continue; + } + + AddOne(rep); + } +} + +SandboxReporter::Snapshot SandboxReporter::GetSnapshot() { + Snapshot snapshot; + MutexAutoLock lock(mMutex); + + const uint64_t bufSize = static_cast<uint64_t>(kSandboxReporterBufferSize); + const uint64_t start = std::max(mCount, bufSize) - bufSize; + snapshot.mOffset = start; + snapshot.mReports.Clear(); + snapshot.mReports.SetCapacity(mCount - start); + for (size_t i = start; i < mCount; ++i) { + const SandboxReport* rep = &mBuffer[i % kSandboxReporterBufferSize]; + MOZ_ASSERT(rep->IsValid()); + snapshot.mReports.AppendElement(*rep); + } + return snapshot; +} + +} // namespace mozilla diff --git a/security/sandbox/linux/reporter/SandboxReporter.h b/security/sandbox/linux/reporter/SandboxReporter.h new file mode 100644 index 0000000000..0969111c9c --- /dev/null +++ b/security/sandbox/linux/reporter/SandboxReporter.h @@ -0,0 +1,86 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_SandboxReporter_h +#define mozilla_SandboxReporter_h + +#include "SandboxReporterCommon.h" + +#include "base/platform_thread.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/Mutex.h" +#include "mozilla/Types.h" +#include "mozilla/UniquePtr.h" +#include "nsTArray.h" + +namespace mozilla { + +// This object collects the SandboxReport messages from all of the +// child processes, submits them to Telemetry, and maintains a ring +// buffer of the last kSandboxReporterBufferSize reports. +class SandboxReporter final : public PlatformThread::Delegate { + public: + // For normal use, don't construct this directly; use the + // Singleton() method. + // + // For unit testing, use this constructor followed by the Init + // method; the object isn't usable unless Init returns true. + explicit SandboxReporter(); + ~SandboxReporter(); + + // See above; this method is not thread-safe. + bool Init(); + + // Used in GeckoChildProcessHost to connect the child process's + // client to this report collector. + void GetClientFileDescriptorMapping(int* aSrcFd, int* aDstFd) const; + + // A snapshot of the report ring buffer; element 0 of `mReports` is + // the `mOffset`th report to be received, and so on. + struct Snapshot { + // The buffer has to fit in memory, but the total number of + // reports received in the session can increase without bound and + // could potentially overflow a uint32_t, so this is 64-bit. + // (It's exposed to JS as a 53-bit int, effectively, but that + // should also be large enough.) + uint64_t mOffset; + nsTArray<SandboxReport> mReports; + }; + + // Read the ring buffer contents; this method is thread-safe. + Snapshot GetSnapshot(); + + // Gets or creates the singleton report collector. Crashes if + // initialization fails (if a socketpair and/or thread can't be + // created, there was almost certainly about to be a crash anyway). + // Thread-safe as long as the pointer isn't used during/after XPCOM + // shutdown. + static SandboxReporter* Singleton(); + + private: + // These are constant over the life of the object: + int mClientFd; + int mServerFd; + PlatformThreadHandle mThread; + + Mutex mMutex MOZ_UNANNOTATED; + // These are protected by mMutex: + UniquePtr<SandboxReport[]> mBuffer; + uint64_t mCount; + + static StaticAutoPtr<SandboxReporter> sSingleton; + + void ThreadMain(void) override; + void AddOne(const SandboxReport& aReport); +}; + +// This is a constant so the % operations can be optimized. This is +// exposed in the header so that unit tests can see it. +static const size_t kSandboxReporterBufferSize = 32; + +} // namespace mozilla + +#endif // mozilla_SandboxReporter_h diff --git a/security/sandbox/linux/reporter/SandboxReporterCommon.h b/security/sandbox/linux/reporter/SandboxReporterCommon.h new file mode 100644 index 0000000000..9bfb40bb98 --- /dev/null +++ b/security/sandbox/linux/reporter/SandboxReporterCommon.h @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_SandboxReporterCommon_h +#define mozilla_SandboxReporterCommon_h + +#include "mozilla/IntegerTypeTraits.h" +#include "mozilla/Types.h" + +#include <sys/types.h> + +// Note: this is also used in libmozsandbox, so dependencies on +// symbols from libxul probably won't work. + +namespace mozilla { +static const size_t kSandboxSyscallArguments = 6; +// fds 0-2: stdio; fd 3: IPC; fd 4: crash reporter. (The IPC child +// process launching code will check that we don't try to use the same +// fd twice.) +static const int kSandboxReporterFileDesc = 5; + +// This struct represents a system call that was rejected by a +// seccomp-bpf policy. +struct SandboxReport { + // In the future this may include finer distinctions than + // GeckoProcessType -- e.g., whether a content process can load + // file:/// URLs, or if it's reserved for content with certain + // user-granted permissions. + enum class ProcType : uint8_t { + CONTENT, + FILE, + MEDIA_PLUGIN, + RDD, + SOCKET_PROCESS, + UTILITY, + }; + + // The syscall number and arguments are usually `unsigned long`, but + // that causes ambiguous overload errors with nsACString::AppendInt. + using ULong = UnsignedStdintTypeForSize<sizeof(unsigned long)>::Type; + + // This time uses CLOCK_MONOTONIC_COARSE. Displaying or reporting + // it should usually be done relative to the current value of that + // clock (or the time at some other event of interest, like a + // subsequent crash). + struct timespec mTime; + + // The pid/tid values, like every other field in this struct, aren't + // authenticated and a compromised process could send anything, so + // use the values with caution. + pid_t mPid; + pid_t mTid; + ProcType mProcType; + ULong mSyscall; + ULong mArgs[kSandboxSyscallArguments]; + + SandboxReport() : mPid(0) {} + bool IsValid() const { return mPid > 0; } +}; + +} // namespace mozilla + +#endif // mozilla_SandboxReporterCommon_h diff --git a/security/sandbox/linux/reporter/SandboxReporterWrappers.cpp b/security/sandbox/linux/reporter/SandboxReporterWrappers.cpp new file mode 100644 index 0000000000..755e8e858d --- /dev/null +++ b/security/sandbox/linux/reporter/SandboxReporterWrappers.cpp @@ -0,0 +1,199 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozISandboxReporter.h" +#include "SandboxReporter.h" + +#include <time.h> + +#include "mozilla/Assertions.h" +#include "mozilla/Components.h" +#include "nsCOMPtr.h" +#include "nsPrintfCString.h" +#include "nsTArray.h" +#include "nsXULAppAPI.h" + +using namespace mozilla; + +namespace mozilla { + +class SandboxReportWrapper final : public mozISandboxReport { + public: + NS_DECL_ISUPPORTS + NS_DECL_MOZISANDBOXREPORT + + explicit SandboxReportWrapper(const SandboxReport& aReport) + : mReport(aReport) {} + + private: + ~SandboxReportWrapper() = default; + SandboxReport mReport; +}; + +NS_IMPL_ISUPPORTS(SandboxReportWrapper, mozISandboxReport) + +/* readonly attribute uint64_t msecAgo; */ +NS_IMETHODIMP SandboxReportWrapper::GetMsecAgo(uint64_t* aMsec) { + struct timespec then = mReport.mTime, now = {0, 0}; + clock_gettime(CLOCK_MONOTONIC_COARSE, &now); + + const uint64_t now_msec = uint64_t(now.tv_sec) * 1000 + now.tv_nsec / 1000000; + const uint64_t then_msec = + uint64_t(then.tv_sec) * 1000 + then.tv_nsec / 1000000; + MOZ_DIAGNOSTIC_ASSERT(now_msec >= then_msec); + if (now_msec >= then_msec) { + *aMsec = now_msec - then_msec; + } else { + *aMsec = 0; + } + return NS_OK; +} + +/* readonly attribute int32_t pid; */ +NS_IMETHODIMP SandboxReportWrapper::GetPid(int32_t* aPid) { + *aPid = mReport.mPid; + return NS_OK; +} + +/* readonly attribute int32_t tid; */ +NS_IMETHODIMP SandboxReportWrapper::GetTid(int32_t* aTid) { + *aTid = mReport.mTid; + return NS_OK; +} + +/* readonly attribute ACString procType; */ +NS_IMETHODIMP SandboxReportWrapper::GetProcType(nsACString& aProcType) { + switch (mReport.mProcType) { + case SandboxReport::ProcType::CONTENT: + aProcType.AssignLiteral("content"); + return NS_OK; + case SandboxReport::ProcType::FILE: + aProcType.AssignLiteral("file"); + return NS_OK; + case SandboxReport::ProcType::MEDIA_PLUGIN: + aProcType.AssignLiteral("mediaPlugin"); + return NS_OK; + case SandboxReport::ProcType::RDD: + aProcType.AssignLiteral("dataDecoder"); + return NS_OK; + case SandboxReport::ProcType::SOCKET_PROCESS: + aProcType.AssignLiteral("socketProcess"); + return NS_OK; + case SandboxReport::ProcType::UTILITY: + aProcType.AssignLiteral("utility"); + return NS_OK; + default: + MOZ_ASSERT(false); + return NS_ERROR_UNEXPECTED; + } +} + +/* readonly attribute uint32_t syscall; */ +NS_IMETHODIMP SandboxReportWrapper::GetSyscall(uint32_t* aSyscall) { + *aSyscall = static_cast<uint32_t>(mReport.mSyscall); + MOZ_ASSERT(static_cast<SandboxReport::ULong>(*aSyscall) == mReport.mSyscall); + return NS_OK; +} + +/* readonly attribute uint32_t numArgs; */ +NS_IMETHODIMP SandboxReportWrapper::GetNumArgs(uint32_t* aNumArgs) { + *aNumArgs = static_cast<uint32_t>(kSandboxSyscallArguments); + return NS_OK; +} + +/* ACString getArg (in uint32_t aIndex); */ +NS_IMETHODIMP SandboxReportWrapper::GetArg(uint32_t aIndex, + nsACString& aRetval) { + if (aIndex >= kSandboxSyscallArguments) { + return NS_ERROR_INVALID_ARG; + } + const auto arg = mReport.mArgs[aIndex]; + nsAutoCString str; + // Use decimal for smaller numbers (more likely ints) and hex for + // larger (more likely pointers). This cutoff is arbitrary. + if (arg >= 1000000) { + str.AppendLiteral("0x"); + str.AppendInt(arg, 16); + } else { + str.AppendInt(arg, 10); + } + aRetval = str; + return NS_OK; +} + +class SandboxReportArray final : public mozISandboxReportArray { + public: + NS_DECL_ISUPPORTS + NS_DECL_MOZISANDBOXREPORTARRAY + + explicit SandboxReportArray(SandboxReporter::Snapshot&& aSnap) + : mOffset(aSnap.mOffset), mArray(std::move(aSnap.mReports)) {} + + private: + ~SandboxReportArray() = default; + uint64_t mOffset; + nsTArray<SandboxReport> mArray; +}; + +NS_IMPL_ISUPPORTS(SandboxReportArray, mozISandboxReportArray) + +/* readonly attribute uint64_t begin; */ +NS_IMETHODIMP SandboxReportArray::GetBegin(uint64_t* aBegin) { + *aBegin = mOffset; + return NS_OK; +} + +/* readonly attribute uint64_t end; */ +NS_IMETHODIMP SandboxReportArray::GetEnd(uint64_t* aEnd) { + *aEnd = mOffset + mArray.Length(); + return NS_OK; +} + +/* mozISandboxReport getElement (in uint64_t aIndex); */ +NS_IMETHODIMP SandboxReportArray::GetElement(uint64_t aIndex, + mozISandboxReport** aRetval) { + uint64_t relIndex = aIndex - mOffset; + if (relIndex >= mArray.Length()) { + return NS_ERROR_INVALID_ARG; + } + + nsCOMPtr<mozISandboxReport> wrapper = + new SandboxReportWrapper(mArray[relIndex]); + wrapper.forget(aRetval); + return NS_OK; +} + +class SandboxReporterWrapper final : public mozISandboxReporter { + public: + NS_DECL_ISUPPORTS + NS_DECL_MOZISANDBOXREPORTER + + SandboxReporterWrapper() = default; + + private: + ~SandboxReporterWrapper() = default; +}; + +NS_IMPL_ISUPPORTS(SandboxReporterWrapper, mozISandboxReporter) + +/* mozISandboxReportArray snapshot(); */ +NS_IMETHODIMP SandboxReporterWrapper::Snapshot( + mozISandboxReportArray** aRetval) { + if (!XRE_IsParentProcess()) { + return NS_ERROR_NOT_AVAILABLE; + } + + nsCOMPtr<mozISandboxReportArray> wrapper = + new SandboxReportArray(SandboxReporter::Singleton()->GetSnapshot()); + wrapper.forget(aRetval); + return NS_OK; +} + +} // namespace mozilla + +NS_IMPL_COMPONENT_FACTORY(mozISandboxReporter) { + return MakeAndAddRef<SandboxReporterWrapper>().downcast<nsISupports>(); +} diff --git a/security/sandbox/linux/reporter/components.conf b/security/sandbox/linux/reporter/components.conf new file mode 100644 index 0000000000..7bd278f349 --- /dev/null +++ b/security/sandbox/linux/reporter/components.conf @@ -0,0 +1,13 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Classes = [ + { + 'cid': '{5118a6f9-2493-4f97-9552-620663e03cb3}', + 'contract_ids': ['@mozilla.org/sandbox/syscall-reporter;1'], + 'type': 'mozISandboxReporter', + }, +] diff --git a/security/sandbox/linux/reporter/moz.build b/security/sandbox/linux/reporter/moz.build new file mode 100644 index 0000000000..ebc11c5ab6 --- /dev/null +++ b/security/sandbox/linux/reporter/moz.build @@ -0,0 +1,36 @@ +# -*- Mode: python; python-indent: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +EXPORTS.mozilla += [ + "SandboxReporter.h", + "SandboxReporterCommon.h", +] + +UNIFIED_SOURCES += [ + "SandboxReporter.cpp", + "SandboxReporterWrappers.cpp", +] + +XPCOM_MANIFESTS += [ + "components.conf", +] + +LOCAL_INCLUDES += [ + "/security/sandbox/linux", # SandboxLogging.h +] + +# Need this for base::PlatformThread +include("/ipc/chromium/chromium-config.mozbuild") + +# Need this for safe_sprintf.h used by SandboxLogging.h, +# but it has to be after ipc/chromium/src. +LOCAL_INCLUDES += [ + "/security/sandbox/chromium", +] + +FINAL_LIBRARY = "xul" + +REQUIRES_UNIFIED_BUILD = True |