Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Unified Diff: chrome/browser/android/seccomp_support_detector.cc

Issue 1018953004: Add SeccompSupportDetector for Android. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: DCHECK Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/seccomp_support_detector.cc
diff --git a/chrome/browser/android/seccomp_support_detector.cc b/chrome/browser/android/seccomp_support_detector.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f33157eb6657f4a524e8894c8d7c3683eb484876
--- /dev/null
+++ b/chrome/browser/android/seccomp_support_detector.cc
@@ -0,0 +1,134 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/seccomp_support_detector.h"
+
+#include <stdio.h>
+#include <sys/utsname.h>
+
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/metrics/histogram_macros.h"
+#include "chrome/common/chrome_utility_messages.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/utility_process_host.h"
+
+using content::BrowserThread;
+
+enum AndroidSeccompStatus {
+ DETECTION_FAILED, // The process crashed during detection.
+ NOT_SUPPORTED, // Kernel has no seccomp support.
+ SUPPORTED, // Kernel has seccomp support.
+ LAST_STATUS
+};
+
+// static
+void SeccompSupportDetector::StartDetection() {
+ // This is instantiated here, and then ownership is maintained by the
+ // Closure objects when the object is being passed between threads. A
+ // reference is also taken by the UtilityProcessHost, which will release
+ // it when the process exits.
+ scoped_refptr<SeccompSupportDetector> detector(new SeccompSupportDetector());
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
Lei Zhang 2015/03/19 00:42:23 BrowserThread::PostBlockingPoolTask
Robert Sesek 2015/03/19 14:57:29 Done.
+ base::Bind(&SeccompSupportDetector::DetectKernelVersion, detector));
+}
+
+SeccompSupportDetector::SeccompSupportDetector() : prctl_detected_(false) {
+}
+
+SeccompSupportDetector::~SeccompSupportDetector() {
+}
+
+void SeccompSupportDetector::DetectKernelVersion() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ // This method will report the kernel major and minor versions by
+ // taking the lower 16 bits of each version number and combining
+ // the two into a 32-bit number.
+
+ // Support known Android kernel versions, and leave room up to 4.10.
+ const int kVersionRanges[] = {
+ 0x00020006,
+ 0x00030000,
+ 0x00030003,
+ 0x00030004,
+ 0x00030008,
+ 0x00030010,
+ 0x00030014,
+ 0x00030017,
+ 0x00030018,
+ 0x00030019,
+ 0x00040000,
+ 0x00040001,
+ 0x00040010,
+ };
+
+ utsname uts;
+ if (uname(&uts) == 0) {
+ int major, minor;
+ if (sscanf(uts.release, "%d.%d", &major, &minor) == 2) {
+ int version = ((major & 0xFFFF) << 16) | (minor & 0xFFFF);
+ UMA_HISTOGRAM_CUSTOM_ENUMERATION(
Ilya Sherman 2015/03/19 00:37:43 nit: Maybe a sparse enum would be simpler to use h
Robert Sesek 2015/03/19 14:57:29 I didn't know about that. Yes, done.
+ "Android.KernelVersion", version,
+ base::CustomHistogram::ArrayToCustomRanges(
+ kVersionRanges, arraysize(kVersionRanges)));
+ }
+ }
+
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ base::Bind(&SeccompSupportDetector::DetectSeccomp, this));
+}
+
+void SeccompSupportDetector::DetectSeccomp() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
Lei Zhang 2015/03/19 00:42:23 DCHECK_CURRENTLY_ON() is the new hotness. Add it t
Robert Sesek 2015/03/19 14:57:29 Nifty. Thanks for the tip.
+
+ content::UtilityProcessHost* utility_process_host =
+ content::UtilityProcessHost::Create(
+ this, base::MessageLoopProxy::current());
+ utility_process_host->Send(new ChromeUtilityMsg_DetectSeccompSupport());
+}
+
+void SeccompSupportDetector::OnProcessCrashed(int exit_code) {
+ // The process crashed. Since prctl detection happens first, report which
+ // probe failed.
+ if (prctl_detected_) {
+ UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Syscall",
+ DETECTION_FAILED,
+ LAST_STATUS);
+ } else {
+ UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Prctl",
Ilya Sherman 2015/03/19 00:37:44 Optional: I'd recommend having a single codepath p
Robert Sesek 2015/03/19 14:57:29 I gave this a go, but it results in two one-line m
+ DETECTION_FAILED,
+ LAST_STATUS);
+ }
+}
+
+bool SeccompSupportDetector::OnMessageReceived(const IPC::Message& message) {
+ bool handled = false;
+ IPC_BEGIN_MESSAGE_MAP(SeccompSupportDetector, message)
+ IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DetectSeccompSupport_ResultPrctl,
+ OnDetectPrctl)
+ IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DetectSeccompSupport_ResultSyscall,
+ OnDetectSyscall)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void SeccompSupportDetector::OnDetectPrctl(bool prctl_supported) {
+ prctl_detected_ = true;
+
+ UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Prctl",
+ prctl_supported ? SUPPORTED : NOT_SUPPORTED,
+ LAST_STATUS);
+}
+
+void SeccompSupportDetector::OnDetectSyscall(bool syscall_supported) {
+ DCHECK(prctl_detected_);
+
+ UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Syscall",
+ syscall_supported ? SUPPORTED : NOT_SUPPORTED,
+ LAST_STATUS);
+
+ // The utility process will shutdown after this, and this object will
+ // be deleted when the UtilityProcessHost releases its reference.
+}

Powered by Google App Engine
This is Rietveld 408576698