summaryrefslogtreecommitdiffstats
path: root/security/sandbox/linux/SandboxReporterClient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/linux/SandboxReporterClient.cpp')
-rw-r--r--security/sandbox/linux/SandboxReporterClient.cpp88
1 files changed, 88 insertions, 0 deletions
diff --git a/security/sandbox/linux/SandboxReporterClient.cpp b/security/sandbox/linux/SandboxReporterClient.cpp
new file mode 100644
index 0000000000..6359c2cb9a
--- /dev/null
+++ b/security/sandbox/linux/SandboxReporterClient.cpp
@@ -0,0 +1,88 @@
+/* -*- 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 "SandboxReporterClient.h"
+#include "SandboxLogging.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include "mozilla/Assertions.h"
+#include "mozilla/PodOperations.h"
+#include "prenv.h"
+#include "sandbox/linux/bpf_dsl/seccomp_macros.h"
+#ifdef ANDROID
+# include "sandbox/linux/system_headers/linux_ucontext.h"
+#else
+# include <ucontext.h>
+#endif
+
+namespace mozilla {
+
+SandboxReporterClient::SandboxReporterClient(SandboxReport::ProcType aProcType,
+ int aFd)
+ : mProcType(aProcType), mFd(aFd) {
+ // Unfortunately, there isn't a good way to check that the fd is a
+ // socket connected to the right thing without attempting some kind
+ // of in-band handshake. However, the crash reporter (which also
+ // uses a "magic number" fd) doesn't do any kind of checking either,
+ // so it's probably okay to skip it here.
+}
+
+SandboxReporterClient::SandboxReporterClient(SandboxReport::ProcType aProcType)
+ : SandboxReporterClient(aProcType, kSandboxReporterFileDesc) {
+ MOZ_RELEASE_ASSERT(PR_GetEnv("MOZ_SANDBOXED") != nullptr);
+}
+
+SandboxReport SandboxReporterClient::MakeReport(const void* aContext) {
+ SandboxReport report;
+ const auto ctx = static_cast<const ucontext_t*>(aContext);
+
+ // Zero the entire struct; some memory safety analyses care about
+ // sending uninitialized alignment padding to another process.
+ PodZero(&report);
+
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &report.mTime);
+ report.mPid = getpid();
+ report.mTid = syscall(__NR_gettid);
+ report.mProcType = mProcType;
+ report.mSyscall = SECCOMP_SYSCALL(ctx);
+ report.mArgs[0] = SECCOMP_PARM1(ctx);
+ report.mArgs[1] = SECCOMP_PARM2(ctx);
+ report.mArgs[2] = SECCOMP_PARM3(ctx);
+ report.mArgs[3] = SECCOMP_PARM4(ctx);
+ report.mArgs[4] = SECCOMP_PARM5(ctx);
+ report.mArgs[5] = SECCOMP_PARM6(ctx);
+ // Named Return Value Optimization allows the compiler to optimize
+ // out the copy here (and the one in MakeReportAndSend).
+ return report;
+}
+
+void SandboxReporterClient::SendReport(const SandboxReport& aReport) {
+ // The "common" seccomp-bpf policy allows sendmsg but not send(to),
+ // so just use sendmsg even though send would suffice for this.
+ struct iovec iov;
+ struct msghdr msg;
+
+ iov.iov_base = const_cast<void*>(static_cast<const void*>(&aReport));
+ iov.iov_len = sizeof(SandboxReport);
+ PodZero(&msg);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+
+ const auto sent = sendmsg(mFd, &msg, MSG_NOSIGNAL);
+
+ if (sent != sizeof(SandboxReport)) {
+ MOZ_DIAGNOSTIC_ASSERT(sent == -1);
+ SANDBOX_LOG_ERRNO("Failed to report rejected syscall");
+ }
+}
+
+} // namespace mozilla