diff options
Diffstat (limited to 'security/sandbox/linux/reporter/SandboxReporterWrappers.cpp')
-rw-r--r-- | security/sandbox/linux/reporter/SandboxReporterWrappers.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
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>(); +} |