 Chromium Code Reviews
 Chromium Code Reviews Issue 1018953004:
  Add SeccompSupportDetector for Android.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1018953004:
  Add SeccompSupportDetector for Android.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/android/seccomp_support_detector.h" | |
| 6 | |
| 7 #include <stdio.h> | |
| 8 #include <sys/utsname.h> | |
| 9 | |
| 10 #include "base/message_loop/message_loop_proxy.h" | |
| 11 #include "base/metrics/histogram_macros.h" | |
| 12 #include "chrome/common/chrome_utility_messages.h" | |
| 13 #include "content/public/browser/browser_thread.h" | |
| 14 #include "content/public/browser/utility_process_host.h" | |
| 15 | |
| 16 using content::BrowserThread; | |
| 17 | |
| 18 enum AndroidSeccompStatus { | |
| 19 DETECTION_FAILED, // The process crashed during detection. | |
| 20 NOT_SUPPORTED, // Kernel has no seccomp support. | |
| 21 SUPPORTED, // Kernel has seccomp support. | |
| 22 LAST_STATUS | |
| 23 }; | |
| 24 | |
| 25 // static | |
| 26 void SeccompSupportDetector::StartDetection() { | |
| 27 // This is instantiated here, and then ownership is maintained by the | |
| 28 // Closure objects when the object is being passed between threads. A | |
| 29 // reference is also taken by the UtilityProcessHost, which will release | |
| 30 // it when the process exits. | |
| 31 scoped_refptr<SeccompSupportDetector> detector(new SeccompSupportDetector()); | |
| 32 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.
 | |
| 33 base::Bind(&SeccompSupportDetector::DetectKernelVersion, detector)); | |
| 34 } | |
| 35 | |
| 36 SeccompSupportDetector::SeccompSupportDetector() : prctl_detected_(false) { | |
| 37 } | |
| 38 | |
| 39 SeccompSupportDetector::~SeccompSupportDetector() { | |
| 40 } | |
| 41 | |
| 42 void SeccompSupportDetector::DetectKernelVersion() { | |
| 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 44 | |
| 45 // This method will report the kernel major and minor versions by | |
| 46 // taking the lower 16 bits of each version number and combining | |
| 47 // the two into a 32-bit number. | |
| 48 | |
| 49 // Support known Android kernel versions, and leave room up to 4.10. | |
| 50 const int kVersionRanges[] = { | |
| 51 0x00020006, | |
| 52 0x00030000, | |
| 53 0x00030003, | |
| 54 0x00030004, | |
| 55 0x00030008, | |
| 56 0x00030010, | |
| 57 0x00030014, | |
| 58 0x00030017, | |
| 59 0x00030018, | |
| 60 0x00030019, | |
| 61 0x00040000, | |
| 62 0x00040001, | |
| 63 0x00040010, | |
| 64 }; | |
| 65 | |
| 66 utsname uts; | |
| 67 if (uname(&uts) == 0) { | |
| 68 int major, minor; | |
| 69 if (sscanf(uts.release, "%d.%d", &major, &minor) == 2) { | |
| 70 int version = ((major & 0xFFFF) << 16) | (minor & 0xFFFF); | |
| 71 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.
 | |
| 72 "Android.KernelVersion", version, | |
| 73 base::CustomHistogram::ArrayToCustomRanges( | |
| 74 kVersionRanges, arraysize(kVersionRanges))); | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, | |
| 79 base::Bind(&SeccompSupportDetector::DetectSeccomp, this)); | |
| 80 } | |
| 81 | |
| 82 void SeccompSupportDetector::DetectSeccomp() { | |
| 83 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.
 | |
| 84 | |
| 85 content::UtilityProcessHost* utility_process_host = | |
| 86 content::UtilityProcessHost::Create( | |
| 87 this, base::MessageLoopProxy::current()); | |
| 88 utility_process_host->Send(new ChromeUtilityMsg_DetectSeccompSupport()); | |
| 89 } | |
| 90 | |
| 91 void SeccompSupportDetector::OnProcessCrashed(int exit_code) { | |
| 92 // The process crashed. Since prctl detection happens first, report which | |
| 93 // probe failed. | |
| 94 if (prctl_detected_) { | |
| 95 UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Syscall", | |
| 96 DETECTION_FAILED, | |
| 97 LAST_STATUS); | |
| 98 } else { | |
| 99 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
 | |
| 100 DETECTION_FAILED, | |
| 101 LAST_STATUS); | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 bool SeccompSupportDetector::OnMessageReceived(const IPC::Message& message) { | |
| 106 bool handled = false; | |
| 107 IPC_BEGIN_MESSAGE_MAP(SeccompSupportDetector, message) | |
| 108 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DetectSeccompSupport_ResultPrctl, | |
| 109 OnDetectPrctl) | |
| 110 IPC_MESSAGE_HANDLER(ChromeUtilityHostMsg_DetectSeccompSupport_ResultSyscall, | |
| 111 OnDetectSyscall) | |
| 112 IPC_MESSAGE_UNHANDLED(handled = false) | |
| 113 IPC_END_MESSAGE_MAP() | |
| 114 return handled; | |
| 115 } | |
| 116 | |
| 117 void SeccompSupportDetector::OnDetectPrctl(bool prctl_supported) { | |
| 118 prctl_detected_ = true; | |
| 119 | |
| 120 UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Prctl", | |
| 121 prctl_supported ? SUPPORTED : NOT_SUPPORTED, | |
| 122 LAST_STATUS); | |
| 123 } | |
| 124 | |
| 125 void SeccompSupportDetector::OnDetectSyscall(bool syscall_supported) { | |
| 126 DCHECK(prctl_detected_); | |
| 127 | |
| 128 UMA_HISTOGRAM_ENUMERATION("Android.SeccompStatus.Syscall", | |
| 129 syscall_supported ? SUPPORTED : NOT_SUPPORTED, | |
| 130 LAST_STATUS); | |
| 131 | |
| 132 // The utility process will shutdown after this, and this object will | |
| 133 // be deleted when the UtilityProcessHost releases its reference. | |
| 134 } | |
| OLD | NEW |