1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsSandboxViolationSink.h"
8 #import <Foundation/NSObjCRuntime.h>
13 #include <dispatch/dispatch.h>
15 #include "mozilla/Preferences.h"
16 #include "mozilla/Sprintf.h"
18 int nsSandboxViolationSink::mNotifyToken = 0;
19 uint64_t nsSandboxViolationSink::mLastMsgReceived = 0;
21 void nsSandboxViolationSink::Start() {
25 notify_register_dispatch(
26 SANDBOX_VIOLATION_NOTIFICATION_NAME, &mNotifyToken,
27 dispatch_queue_create(SANDBOX_VIOLATION_QUEUE_NAME, DISPATCH_QUEUE_SERIAL), ^(int token) {
32 void nsSandboxViolationSink::Stop() {
36 notify_cancel(mNotifyToken);
40 // We need to query syslogd to find out what violations occurred, and whether
41 // they were "ours". We can use the Apple System Log facility to do this.
42 // Besides calling notify_post("com.apple.sandbox.violation.*"), Apple's
43 // sandboxd also reports all sandbox violations (sent to it by the Sandbox
44 // kernel extension) to syslogd, which stores them and makes them viewable
45 // in the system console. This is the database we query.
47 // ViolationHandler() is always called on its own secondary thread. This
48 // makes it unlikely it will interfere with other browser activity.
50 void nsSandboxViolationSink::ViolationHandler() {
51 aslmsg query = asl_new(ASL_TYPE_QUERY);
53 asl_set_query(query, ASL_KEY_FACILITY, "com.apple.sandbox", ASL_QUERY_OP_EQUAL);
55 // Only get reports that were generated very recently.
56 char query_time[30] = {0};
57 SprintfLiteral(query_time, "%li", time(NULL) - 2);
58 asl_set_query(query, ASL_KEY_TIME, query_time, ASL_QUERY_OP_NUMERIC | ASL_QUERY_OP_GREATER_EQUAL);
60 // This code is easier to test if we don't just track "our" violations,
61 // which are (normally) few and far between. For example (for the time
62 // being at least) four appleeventsd sandbox violations happen every time
63 // we start the browser in e10s mode. But it makes sense to default to
64 // only tracking "our" violations.
65 if (mozilla::Preferences::GetBool("security.sandbox.mac.track.violations.oursonly", true)) {
66 // This makes each of our processes log its own violations. It might
67 // be better to make the chrome process log all the other processes'
69 char query_pid[20] = {0};
70 SprintfLiteral(query_pid, "%u", getpid());
71 asl_set_query(query, ASL_KEY_REF_PID, query_pid, ASL_QUERY_OP_EQUAL);
74 aslresponse response = asl_search(nullptr, query);
76 // Each time ViolationHandler() is called we grab as many messages as are
77 // available. Otherwise we might not get them all.
81 aslmsg found = nullptr;
84 while ((hit = aslresponse_next(response))) {
85 // Record the message id to avoid logging the same violation more
87 id_str = asl_get(hit, ASL_KEY_MSG_ID);
88 uint64_t id_val = atoll(id_str);
89 if (id_val <= mLastMsgReceived) {
92 mLastMsgReceived = id_val;
100 const char* pid_str = asl_get(found, ASL_KEY_REF_PID);
101 const char* message_str = asl_get(found, ASL_KEY_MSG);
102 NSLog(@"nsSandboxViolationSink::ViolationHandler(): id %s, pid %s, message %s", id_str,
103 pid_str, message_str);
105 aslresponse_free(response);