SandboxReporterWrappers.cpp (5704B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozISandboxReporter.h" 8 #include "SandboxReporter.h" 9 10 #include <time.h> 11 12 #include "mozilla/Assertions.h" 13 #include "mozilla/Components.h" 14 #include "nsCOMPtr.h" 15 #include "nsPrintfCString.h" 16 #include "nsTArray.h" 17 #include "nsXULAppAPI.h" 18 19 using namespace mozilla; 20 21 namespace mozilla { 22 23 class SandboxReportWrapper final : public mozISandboxReport { 24 public: 25 NS_DECL_ISUPPORTS 26 NS_DECL_MOZISANDBOXREPORT 27 28 explicit SandboxReportWrapper(const SandboxReport& aReport) 29 : mReport(aReport) {} 30 31 private: 32 ~SandboxReportWrapper() = default; 33 SandboxReport mReport; 34 }; 35 36 NS_IMPL_ISUPPORTS(SandboxReportWrapper, mozISandboxReport) 37 38 /* readonly attribute uint64_t msecAgo; */ 39 NS_IMETHODIMP SandboxReportWrapper::GetMsecAgo(uint64_t* aMsec) { 40 struct timespec then = mReport.mTime, now = {0, 0}; 41 clock_gettime(CLOCK_MONOTONIC_COARSE, &now); 42 43 const uint64_t now_msec = uint64_t(now.tv_sec) * 1000 + now.tv_nsec / 1000000; 44 const uint64_t then_msec = 45 uint64_t(then.tv_sec) * 1000 + then.tv_nsec / 1000000; 46 MOZ_DIAGNOSTIC_ASSERT(now_msec >= then_msec); 47 if (now_msec >= then_msec) { 48 *aMsec = now_msec - then_msec; 49 } else { 50 *aMsec = 0; 51 } 52 return NS_OK; 53 } 54 55 /* readonly attribute int32_t pid; */ 56 NS_IMETHODIMP SandboxReportWrapper::GetPid(int32_t* aPid) { 57 *aPid = mReport.mPid; 58 return NS_OK; 59 } 60 61 /* readonly attribute int32_t tid; */ 62 NS_IMETHODIMP SandboxReportWrapper::GetTid(int32_t* aTid) { 63 *aTid = mReport.mTid; 64 return NS_OK; 65 } 66 67 /* readonly attribute ACString procType; */ 68 NS_IMETHODIMP SandboxReportWrapper::GetProcType(nsACString& aProcType) { 69 switch (mReport.mProcType) { 70 case SandboxReport::ProcType::CONTENT: 71 aProcType.AssignLiteral("content"); 72 return NS_OK; 73 case SandboxReport::ProcType::FILE: 74 aProcType.AssignLiteral("file"); 75 return NS_OK; 76 case SandboxReport::ProcType::MEDIA_PLUGIN: 77 aProcType.AssignLiteral("mediaPlugin"); 78 return NS_OK; 79 case SandboxReport::ProcType::RDD: 80 aProcType.AssignLiteral("dataDecoder"); 81 return NS_OK; 82 case SandboxReport::ProcType::SOCKET_PROCESS: 83 aProcType.AssignLiteral("socketProcess"); 84 return NS_OK; 85 case SandboxReport::ProcType::UTILITY: 86 aProcType.AssignLiteral("utility"); 87 return NS_OK; 88 default: 89 MOZ_ASSERT(false); 90 return NS_ERROR_UNEXPECTED; 91 } 92 } 93 94 /* readonly attribute uint32_t syscall; */ 95 NS_IMETHODIMP SandboxReportWrapper::GetSyscall(uint32_t* aSyscall) { 96 *aSyscall = static_cast<uint32_t>(mReport.mSyscall); 97 MOZ_ASSERT(static_cast<SandboxReport::ULong>(*aSyscall) == mReport.mSyscall); 98 return NS_OK; 99 } 100 101 /* readonly attribute uint32_t numArgs; */ 102 NS_IMETHODIMP SandboxReportWrapper::GetNumArgs(uint32_t* aNumArgs) { 103 *aNumArgs = static_cast<uint32_t>(kSandboxSyscallArguments); 104 return NS_OK; 105 } 106 107 /* ACString getArg (in uint32_t aIndex); */ 108 NS_IMETHODIMP SandboxReportWrapper::GetArg(uint32_t aIndex, 109 nsACString& aRetval) { 110 if (aIndex >= kSandboxSyscallArguments) { 111 return NS_ERROR_INVALID_ARG; 112 } 113 const auto arg = mReport.mArgs[aIndex]; 114 nsAutoCString str; 115 // Use decimal for smaller numbers (more likely ints) and hex for 116 // larger (more likely pointers). This cutoff is arbitrary. 117 if (arg >= 1000000) { 118 str.AppendLiteral("0x"); 119 str.AppendInt(arg, 16); 120 } else { 121 str.AppendInt(arg, 10); 122 } 123 aRetval = str; 124 return NS_OK; 125 } 126 127 class SandboxReportArray final : public mozISandboxReportArray { 128 public: 129 NS_DECL_ISUPPORTS 130 NS_DECL_MOZISANDBOXREPORTARRAY 131 132 explicit SandboxReportArray(SandboxReporter::Snapshot&& aSnap) 133 : mOffset(aSnap.mOffset), mArray(std::move(aSnap.mReports)) {} 134 135 private: 136 ~SandboxReportArray() = default; 137 uint64_t mOffset; 138 nsTArray<SandboxReport> mArray; 139 }; 140 141 NS_IMPL_ISUPPORTS(SandboxReportArray, mozISandboxReportArray) 142 143 /* readonly attribute uint64_t begin; */ 144 NS_IMETHODIMP SandboxReportArray::GetBegin(uint64_t* aBegin) { 145 *aBegin = mOffset; 146 return NS_OK; 147 } 148 149 /* readonly attribute uint64_t end; */ 150 NS_IMETHODIMP SandboxReportArray::GetEnd(uint64_t* aEnd) { 151 *aEnd = mOffset + mArray.Length(); 152 return NS_OK; 153 } 154 155 /* mozISandboxReport getElement (in uint64_t aIndex); */ 156 NS_IMETHODIMP SandboxReportArray::GetElement(uint64_t aIndex, 157 mozISandboxReport** aRetval) { 158 uint64_t relIndex = aIndex - mOffset; 159 if (relIndex >= mArray.Length()) { 160 return NS_ERROR_INVALID_ARG; 161 } 162 163 nsCOMPtr<mozISandboxReport> wrapper = 164 new SandboxReportWrapper(mArray[relIndex]); 165 wrapper.forget(aRetval); 166 return NS_OK; 167 } 168 169 class SandboxReporterWrapper final : public mozISandboxReporter { 170 public: 171 NS_DECL_ISUPPORTS 172 NS_DECL_MOZISANDBOXREPORTER 173 174 SandboxReporterWrapper() = default; 175 176 private: 177 ~SandboxReporterWrapper() = default; 178 }; 179 180 NS_IMPL_ISUPPORTS(SandboxReporterWrapper, mozISandboxReporter) 181 182 /* mozISandboxReportArray snapshot(); */ 183 NS_IMETHODIMP SandboxReporterWrapper::Snapshot( 184 mozISandboxReportArray** aRetval) { 185 if (!XRE_IsParentProcess()) { 186 return NS_ERROR_NOT_AVAILABLE; 187 } 188 189 nsCOMPtr<mozISandboxReportArray> wrapper = 190 new SandboxReportArray(SandboxReporter::Singleton()->GetSnapshot()); 191 wrapper.forget(aRetval); 192 return NS_OK; 193 } 194 195 } // namespace mozilla 196 197 NS_IMPL_COMPONENT_FACTORY(mozISandboxReporter) { 198 return MakeAndAddRef<SandboxReporterWrapper>().downcast<nsISupports>(); 199 }