SandboxReporterClient.cpp (2828B)
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 "SandboxReporterClient.h" 8 #include "SandboxLogging.h" 9 10 #include <errno.h> 11 #include <signal.h> 12 #include <sys/socket.h> 13 #include <sys/syscall.h> 14 #include <sys/types.h> 15 #include <time.h> 16 17 #include "mozilla/Assertions.h" 18 #include "mozilla/PodOperations.h" 19 #include "prenv.h" 20 #include "sandbox/linux/bpf_dsl/seccomp_macros.h" 21 #ifdef ANDROID 22 # include "sandbox/linux/system_headers/linux_ucontext.h" 23 #else 24 # include <ucontext.h> 25 #endif 26 27 namespace mozilla { 28 29 SandboxReporterClient::SandboxReporterClient(SandboxReport::ProcType aProcType, 30 int aFd) 31 : mProcType(aProcType), mFd(aFd) { 32 // Unfortunately, there isn't a good way to check that the fd is a 33 // socket connected to the right thing without attempting some kind 34 // of in-band handshake. However, the crash reporter (which also 35 // uses a "magic number" fd) doesn't do any kind of checking either, 36 // so it's probably okay to skip it here. 37 } 38 39 SandboxReport SandboxReporterClient::MakeReport(const void* aContext) { 40 SandboxReport report; 41 const auto ctx = static_cast<const ucontext_t*>(aContext); 42 43 // Zero the entire struct; some memory safety analyses care about 44 // sending uninitialized alignment padding to another process. 45 PodZero(&report); 46 47 clock_gettime(CLOCK_MONOTONIC_COARSE, &report.mTime); 48 report.mPid = getpid(); 49 report.mTid = syscall(__NR_gettid); 50 report.mProcType = mProcType; 51 report.mSyscall = SECCOMP_SYSCALL(ctx); 52 report.mArgs[0] = SECCOMP_PARM1(ctx); 53 report.mArgs[1] = SECCOMP_PARM2(ctx); 54 report.mArgs[2] = SECCOMP_PARM3(ctx); 55 report.mArgs[3] = SECCOMP_PARM4(ctx); 56 report.mArgs[4] = SECCOMP_PARM5(ctx); 57 report.mArgs[5] = SECCOMP_PARM6(ctx); 58 // Named Return Value Optimization allows the compiler to optimize 59 // out the copy here (and the one in MakeReportAndSend). 60 return report; 61 } 62 63 void SandboxReporterClient::SendReport(const SandboxReport& aReport) { 64 // The "common" seccomp-bpf policy allows sendmsg but not send(to), 65 // so just use sendmsg even though send would suffice for this. 66 struct iovec iov; 67 struct msghdr msg; 68 69 iov.iov_base = const_cast<void*>(static_cast<const void*>(&aReport)); 70 iov.iov_len = sizeof(SandboxReport); 71 PodZero(&msg); 72 msg.msg_iov = &iov; 73 msg.msg_iovlen = 1; 74 75 const auto sent = sendmsg(mFd, &msg, MSG_NOSIGNAL); 76 77 if (sent != sizeof(SandboxReport)) { 78 MOZ_DIAGNOSTIC_ASSERT(sent == -1); 79 SANDBOX_LOG_ERRNO("Failed to report rejected syscall"); 80 } 81 } 82 83 } // namespace mozilla