diff options
-rw-r--r-- | chrome/browser/chromeos/chrome_browser_main_chromeos.cc | 56 | ||||
-rw-r--r-- | chrome/browser/chromeos/chrome_browser_main_chromeos.h | 4 | ||||
-rw-r--r-- | chrome/browser/low_memory_observer.cc | 10 | ||||
-rw-r--r-- | chrome/browser/low_memory_observer.h | 5 | ||||
-rw-r--r-- | chrome/browser/oom_priority_manager.cc | 45 | ||||
-rw-r--r-- | chrome/browser/ui/views/sad_tab_view.cc | 43 | ||||
-rw-r--r-- | content/browser/zygote_host_impl_linux.cc | 42 | ||||
-rw-r--r-- | content/browser/zygote_host_impl_linux.h | 3 | ||||
-rw-r--r-- | content/public/browser/zygote_host_linux.h | 6 | ||||
-rw-r--r-- | sandbox/linux/suid/process_util.h | 9 | ||||
-rw-r--r-- | sandbox/linux/suid/process_util_linux.c | 35 | ||||
-rw-r--r-- | sandbox/linux/suid/sandbox.c | 28 | ||||
-rw-r--r-- | sandbox/linux/suid/sandbox.h | 24 | ||||
-rw-r--r-- | sandbox/linux/suid/suid_unsafe_environment_variables.h | 8 | ||||
-rw-r--r-- | sandbox/sandbox.gyp | 1 |
15 files changed, 275 insertions, 44 deletions
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index ea86e8f..5563502 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc @@ -49,6 +49,7 @@ #include "chrome/browser/chromeos/web_socket_proxy_controller.h" #include "chrome/browser/chromeos/xinput_hierarchy_changed_event_listener.h" #include "chrome/browser/defaults.h" +#include "chrome/browser/low_memory_observer.h" #include "chrome/browser/metrics/metrics_service.h" #include "chrome/browser/oom_priority_manager.h" #include "chrome/browser/policy/browser_policy_connector.h" @@ -59,6 +60,7 @@ #include "chrome/browser/ui/views/browser_dialogs.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/chrome_version_info.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/pref_names.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -285,6 +287,13 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopStart() { ChromeBrowserMainPartsLinux::PostMainMessageLoopStart(); } +int ChromeBrowserMainPartsChromeos::PreCreateThreads() { + // Set up field trial for low memory headroom settings. + SetupLowMemoryHeadroomFieldTrial(); + + return ChromeBrowserMainPartsLinux::PreCreateThreads(); +} + // Threads are initialized MainMessageLoopStart and MainMessageLoopRun. void ChromeBrowserMainPartsChromeos::PreMainMessageLoopRun() { @@ -495,3 +504,50 @@ void ChromeBrowserMainPartsChromeos::PostMainMessageLoopRun() { ChromeBrowserMainPartsLinux::PostMainMessageLoopRun(); } + +void ChromeBrowserMainPartsChromeos::SetupLowMemoryHeadroomFieldTrial() { + chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel(); + // Only enable this experiment on Canary and Dev, since it's possible + // that this will make the machine unstable. + // Note that to have this code execute in a developer build, + // then chrome::VersionInfo::CHANNEL_UNKNOWN needs to be added here. + if (channel == chrome::VersionInfo::CHANNEL_CANARY || + channel == chrome::VersionInfo::CHANNEL_DEV) { + const base::FieldTrial::Probability kDivisor = 7; + // 1 in 7 probability of being in each group. If the default value for the + // kernel matches one of the experiment groups, then they will have + // identical results. + const base::FieldTrial::Probability kEnableProbability = 1; + scoped_refptr<base::FieldTrial> trial = + base::FieldTrialList::FactoryGetFieldTrial( + "LowMemoryMargin", kDivisor, "default", 2012, 6, 30, NULL); + int disable = trial->AppendGroup("off", kEnableProbability); + int margin_0mb = trial->AppendGroup("0mb", kEnableProbability); + int margin_25mb = trial->AppendGroup("25mb", kEnableProbability); + int margin_50mb = trial->AppendGroup("50mb", kEnableProbability); + int margin_100mb = trial->AppendGroup("100mb", kEnableProbability); + int margin_200mb = trial->AppendGroup("200mb", kEnableProbability); + if (trial->group() == disable) { + LOG(WARNING) << "low_mem: Part of 'off' experiment"; + browser::LowMemoryObserver::SetLowMemoryMargin(0); + } else if (trial->group() == margin_0mb) { + LOG(WARNING) << "low_mem: Part of '0MB' experiment"; + browser::LowMemoryObserver::SetLowMemoryMargin(50); + } else if (trial->group() == margin_25mb) { + LOG(WARNING) << "low_mem: Part of '25MB' experiment"; + browser::LowMemoryObserver::SetLowMemoryMargin(50); + } else if (trial->group() == margin_50mb) { + LOG(WARNING) << "low_mem: Part of '50MB' experiment"; + browser::LowMemoryObserver::SetLowMemoryMargin(50); + } else if (trial->group() == margin_100mb) { + LOG(WARNING) << "low_mem: Part of '100MB' experiment"; + browser::LowMemoryObserver::SetLowMemoryMargin(100); + } else if (trial->group() == margin_200mb) { + LOG(WARNING) << "low_mem: Part of '200MB' experiment"; + browser::LowMemoryObserver::SetLowMemoryMargin(200); + } else { + LOG(WARNING) << "low_mem: Part of 'default' experiment"; + } + } +} + diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h index a001ea1..4cc2a61 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h @@ -30,6 +30,7 @@ class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsLinux { virtual void PreEarlyInitialization() OVERRIDE; virtual void PreMainMessageLoopStart() OVERRIDE; virtual void PostMainMessageLoopStart() OVERRIDE; + virtual int PreCreateThreads() OVERRIDE; virtual void PreMainMessageLoopRun() OVERRIDE; // Stages called from PreMainMessageLoopRun. @@ -40,6 +41,9 @@ class ChromeBrowserMainPartsChromeos : public ChromeBrowserMainPartsLinux { virtual void PostMainMessageLoopRun() OVERRIDE; + // Set up field trial for low memory headroom settings. + void SetupLowMemoryHeadroomFieldTrial(); + private: scoped_ptr<chromeos::BrightnessObserver> brightness_observer_; scoped_ptr<chromeos::ResumeObserver> resume_observer_; diff --git a/chrome/browser/low_memory_observer.cc b/chrome/browser/low_memory_observer.cc index 8788f03..5396696 100644 --- a/chrome/browser/low_memory_observer.cc +++ b/chrome/browser/low_memory_observer.cc @@ -15,6 +15,11 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/oom_priority_manager.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/zygote_host_linux.h" + +#if !defined(OS_CHROMEOS) +#error This file only meant to be compiled on ChromeOS +#endif using content::BrowserThread; @@ -180,4 +185,9 @@ void LowMemoryObserver::Stop() { observer_.get())); } +// static +void LowMemoryObserver::SetLowMemoryMargin(int64 margin_mb) { + content::ZygoteHost::GetInstance()->AdjustLowMemoryMargin(margin_mb); +} + } // namespace browser diff --git a/chrome/browser/low_memory_observer.h b/chrome/browser/low_memory_observer.h index 088a74c..1caad25 100644 --- a/chrome/browser/low_memory_observer.h +++ b/chrome/browser/low_memory_observer.h @@ -34,6 +34,11 @@ class LowMemoryObserver { void Start(); void Stop(); + + // Sets the threshold level of the low memory notifier in megabytes. Setting + // to -1 will turn off the low memory notifier. + static void SetLowMemoryMargin(int64 margin_mb); + private: scoped_refptr<LowMemoryObserverImpl> observer_; diff --git a/chrome/browser/oom_priority_manager.cc b/chrome/browser/oom_priority_manager.cc index 0d87d4c..60fa186 100644 --- a/chrome/browser/oom_priority_manager.cc +++ b/chrome/browser/oom_priority_manager.cc @@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" +#include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" #include "base/process.h" #include "base/process_util.h" @@ -51,14 +52,25 @@ namespace browser { namespace { +// Name of the experiment to run. +const char kExperiment[] = "LowMemoryMargin"; + +#define EXPERIMENT_CUSTOM_COUNTS(name, sample, min, max, buckets) \ + UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, buckets); \ + if (base::FieldTrialList::TrialExists(kExperiment)) \ + UMA_HISTOGRAM_CUSTOM_COUNTS( \ + base::FieldTrial::MakeName(name, kExperiment), \ + sample, min, max, buckets); + // Record a time in seconds, over a potential interval of about a day. Must be a // macro and not a function because the histograms system requires a unique // static variable at the site of each call. -#define UMA_HISTOGRAM_SECONDS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ - name, sample, 1, 10000, 50) +#define EXPERIMENT_HISTOGRAM_SECONDS(name, sample) \ + EXPERIMENT_CUSTOM_COUNTS(name, sample, 1, 10000, 50) + // Record a size in megabytes, over a potential interval up to 32 GB. -#define UMA_HISTOGRAM_MEGABYTES(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \ - name, sample, 1, 32768, 50) +#define EXPERIMENT_HISTOGRAM_MEGABYTES(name, sample) \ + EXPERIMENT_CUSTOM_COUNTS(name, sample, 1, 32768, 50) // The default interval in seconds after which to adjust the oom_score_adj // value. @@ -241,11 +253,11 @@ bool OomPriorityManager::DiscardTabById(int64 target_web_contents_id) { void OomPriorityManager::RecordDiscardStatistics() { // Record a raw count so we can compare to discard reloads. discard_count_++; - UMA_HISTOGRAM_CUSTOM_COUNTS( - "Tabs.Discard.DiscardCount", discard_count_, 1, 1000, 50); + EXPERIMENT_CUSTOM_COUNTS("Tabs.Discard.DiscardCount", + discard_count_, 1, 1000, 50); // TODO(jamescook): Maybe incorporate extension count? - UMA_HISTOGRAM_COUNTS_100("Tabs.Discard.TabCount", GetTabCount()); + EXPERIMENT_CUSTOM_COUNTS("Tabs.Discard.TabCount", GetTabCount(), 1, 100, 50); // TODO(jamescook): If the time stats prove too noisy, then divide up users // based on how heavily they use Chrome using tab count as a proxy. @@ -254,23 +266,24 @@ void OomPriorityManager::RecordDiscardStatistics() { // This is the first discard this session. TimeDelta interval = TimeTicks::Now() - start_time_; int interval_seconds = static_cast<int>(interval.InSeconds()); - UMA_HISTOGRAM_SECONDS("Tabs.Discard.InitialTime", interval_seconds); + EXPERIMENT_HISTOGRAM_SECONDS("Tabs.Discard.InitialTime", interval_seconds); } else { // Not the first discard, so compute time since last discard. TimeDelta interval = TimeTicks::Now() - last_discard_time_; int interval_seconds = static_cast<int>(interval.InSeconds()); - UMA_HISTOGRAM_SECONDS("Tabs.Discard.IntervalTime", interval_seconds); + EXPERIMENT_HISTOGRAM_SECONDS("Tabs.Discard.IntervalTime", interval_seconds); } // Record Chrome's concept of system memory usage at the time of the discard. base::SystemMemoryInfoKB memory; if (base::GetSystemMemoryInfo(&memory)) { - int mem_anonymous_kb = memory.active_anon + memory.inactive_anon; - UMA_HISTOGRAM_MEGABYTES("Tabs.Discard.MemAnonymousMB", - mem_anonymous_kb / 1024); - int mem_available_kb = - memory.active_file + memory.inactive_file + memory.free; - UMA_HISTOGRAM_MEGABYTES("Tabs.Discard.MemAvailableMB", - mem_available_kb / 1024); + int mem_anonymous_mb = (memory.active_anon + memory.inactive_anon) / 1024; + EXPERIMENT_HISTOGRAM_MEGABYTES("Tabs.Discard.MemAnonymousMB", + mem_anonymous_mb); + + int mem_available_mb = + (memory.active_file + memory.inactive_file + memory.free) / 1024; + EXPERIMENT_HISTOGRAM_MEGABYTES("Tabs.Discard.MemAvailableMB", + mem_available_mb); } // Set up to record the next interval. last_discard_time_ = TimeTicks::Now(); diff --git a/chrome/browser/ui/views/sad_tab_view.cc b/chrome/browser/ui/views/sad_tab_view.cc index d64b2ac..566cf9b 100644 --- a/chrome/browser/ui/views/sad_tab_view.cc +++ b/chrome/browser/ui/views/sad_tab_view.cc @@ -6,6 +6,7 @@ #include <string> +#include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" #include "base/utf_string_conversions.h" #include "chrome/browser/feedback/feedback_util.h" @@ -28,23 +29,37 @@ using content::OpenURLParams; using content::WebContents; -static const int kPadding = 20; -static const float kMessageSize = 0.65f; -static const SkColor kTextColor = SK_ColorWHITE; -static const SkColor kCrashColor = SkColorSetRGB(35, 48, 64); -static const SkColor kKillColor = SkColorSetRGB(57, 48, 88); +namespace { + +const int kPadding = 20; +const float kMessageSize = 0.65f; +const SkColor kTextColor = SK_ColorWHITE; +const SkColor kCrashColor = SkColorSetRGB(35, 48, 64); +const SkColor kKillColor = SkColorSetRGB(57, 48, 88); const char kCategoryTagCrash[] = "Crash"; // Font size correction. #if defined(CROS_FONTS_USING_BCI) -static const int kTitleFontSizeDelta = 1; -static const int kMessageFontSizeDelta = 0; +const int kTitleFontSizeDelta = 1; +const int kMessageFontSizeDelta = 0; #else -static const int kTitleFontSizeDelta = 2; -static const int kMessageFontSizeDelta = 1; +const int kTitleFontSizeDelta = 2; +const int kMessageFontSizeDelta = 1; #endif +// Name of the experiment to run. +const char kExperiment[] = "LowMemoryMargin"; + +#define EXPERIMENT_CUSTOM_COUNTS(name, sample, min, max, buckets) \ + UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, buckets); \ + if (base::FieldTrialList::TrialExists(kExperiment)) \ + UMA_HISTOGRAM_CUSTOM_COUNTS( \ + base::FieldTrial::MakeName(name, kExperiment), \ + sample, min, max, buckets); + +} // namespace + SadTabView::SadTabView(WebContents* web_contents, Kind kind) : web_contents_(web_contents), kind_(kind), @@ -70,14 +85,16 @@ SadTabView::SadTabView(WebContents* web_contents, Kind kind) switch (kind_) { case CRASHED: { static int crashed = 0; - UMA_HISTOGRAM_CUSTOM_COUNTS( - "Tabs.SadTab.CrashCreated", ++crashed, 1, 1000, 50); + crashed++; + EXPERIMENT_CUSTOM_COUNTS( + "Tabs.SadTab.CrashCreated", crashed, 1, 1000, 50); break; } case KILLED: { static int killed = 0; - UMA_HISTOGRAM_CUSTOM_COUNTS( - "Tabs.SadTab.KillCreated", ++killed, 1, 1000, 50); + killed++; + EXPERIMENT_CUSTOM_COUNTS( + "Tabs.SadTab.KillCreated", killed, 1, 1000, 50); break; } default: diff --git a/content/browser/zygote_host_impl_linux.cc b/content/browser/zygote_host_impl_linux.cc index 519fa12..40dcc6a 100644 --- a/content/browser/zygote_host_impl_linux.cc +++ b/content/browser/zygote_host_impl_linux.cc @@ -30,6 +30,7 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_switches.h" #include "content/public/common/result_codes.h" +#include "sandbox/linux/suid/sandbox.h" #include "sandbox/linux/suid/suid_unsafe_environment_variables.h" #if defined(USE_TCMALLOC) @@ -371,13 +372,9 @@ void ZygoteHostImpl::AdjustRendererOOMScore(base::ProcessHandle pid, if (IsHeapProfilerRunning()) return; #endif - // The command line switch used for supplying the OOM adjustment score - // to the setuid sandbox. - static const char kAdjustOOMScoreSwitch[] = "--adjust-oom-score"; - std::vector<std::string> adj_oom_score_cmdline; adj_oom_score_cmdline.push_back(sandbox_binary_); - adj_oom_score_cmdline.push_back(kAdjustOOMScoreSwitch); + adj_oom_score_cmdline.push_back(sandbox::kAdjustOOMScoreSwitch); adj_oom_score_cmdline.push_back(base::Int64ToString(pid)); adj_oom_score_cmdline.push_back(base::IntToString(score)); @@ -393,6 +390,41 @@ void ZygoteHostImpl::AdjustRendererOOMScore(base::ProcessHandle pid, } #endif +void ZygoteHostImpl::AdjustLowMemoryMargin(int64 margin_mb) { +#if defined(OS_CHROMEOS) + // You can't change the low memory margin unless you're root. Because of this, + // we can't set the low memory margin from the browser process. + // So, we use the SUID binary to change it for us. + if (using_suid_sandbox_) { +#if defined(USE_TCMALLOC) + // If heap profiling is running, these processes are not exiting, at least + // on ChromeOS. The easiest thing to do is not launch them when profiling. + // TODO(stevenjb): Investigate further and fix. + if (IsHeapProfilerRunning()) + return; +#endif + std::vector<std::string> adj_low_mem_commandline; + adj_low_mem_commandline.push_back(sandbox_binary_); + adj_low_mem_commandline.push_back(sandbox::kAdjustLowMemMarginSwitch); + adj_low_mem_commandline.push_back(base::Int64ToString(margin_mb)); + + base::ProcessHandle sandbox_helper_process; + if (base::LaunchProcess(adj_low_mem_commandline, base::LaunchOptions(), + &sandbox_helper_process)) { + base::EnsureProcessGetsReaped(sandbox_helper_process); + } else { + LOG(ERROR) << "Unable to run suid sandbox to set low memory margin."; + } + } + // Don't adjust memory margin if we're not running with the sandbox: this + // isn't very common, and not doing it has little impact. +#else + // Low memory notification is currently only implemented on ChromeOS. + NOTREACHED() << "AdjustLowMemoryMargin not implemented"; +#endif // defined(OS_CHROMEOS) +} + + void ZygoteHostImpl::EnsureProcessTerminated(pid_t process) { DCHECK(init_); Pickle pickle; diff --git a/content/browser/zygote_host_impl_linux.h b/content/browser/zygote_host_impl_linux.h index 3c6e824..ad8dfac 100644 --- a/content/browser/zygote_host_impl_linux.h +++ b/content/browser/zygote_host_impl_linux.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -55,6 +55,7 @@ class CONTENT_EXPORT ZygoteHostImpl : public content::ZygoteHost { virtual int GetSandboxStatus() const OVERRIDE; virtual void AdjustRendererOOMScore(base::ProcessHandle process_handle, int score) OVERRIDE; + virtual void AdjustLowMemoryMargin(int64 margin_mb) OVERRIDE; private: friend struct DefaultSingletonTraits<ZygoteHostImpl>; diff --git a/content/public/browser/zygote_host_linux.h b/content/public/browser/zygote_host_linux.h index 2b79b30..cd9932e 100644 --- a/content/public/browser/zygote_host_linux.h +++ b/content/public/browser/zygote_host_linux.h @@ -46,6 +46,12 @@ class ZygoteHost { // likely to be killed by the OOM killer. virtual void AdjustRendererOOMScore(base::ProcessHandle process_handle, int score) = 0; + + // Adjust the point at which the low memory notifier in the kernel tells + // us that we're low on memory. When there is less than |margin_mb| left, + // then the notifier will notify us. Set |margin_mb| to -1 to turn off + // low memory notification altogether. + virtual void AdjustLowMemoryMargin(int64 margin_mb) = 0; }; } // namespace content diff --git a/sandbox/linux/suid/process_util.h b/sandbox/linux/suid/process_util.h index 1826555..61f7b25 100644 --- a/sandbox/linux/suid/process_util.h +++ b/sandbox/linux/suid/process_util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -7,6 +7,7 @@ #ifndef SANDBOX_LINUX_SUID_PROCESS_UTIL_H_ #define SANDBOX_LINUX_SUID_PROCESS_UTIL_H_ +#pragma once #include <stdbool.h> #include <sys/types.h> @@ -23,4 +24,10 @@ // values, of course. BASE_EXPORT bool AdjustOOMScore(pid_t process, int score); +// This adjusts /sys/kernel/mm/chromeos-low_mem/margin so that +// the kernel notifies us that we are low on memory when less than +// |margin_mb| megabytes are available. Setting |margin_mb| to -1 +// turns off low memory notification. +BASE_EXPORT bool AdjustLowMemoryMargin(int64_t margin_mb); + #endif // SANDBOX_LINUX_SUID_PROCESS_UTIL_H_ diff --git a/sandbox/linux/suid/process_util_linux.c b/sandbox/linux/suid/process_util_linux.c index 13f45ce..1829558 100644 --- a/sandbox/linux/suid/process_util_linux.c +++ b/sandbox/linux/suid/process_util_linux.c @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -24,6 +24,12 @@ static const int kMaxOomScore = 1000; static const int kMaxOldOomScore = 15; +// Kernel pseudo-file that allows setting of the low memory margin. +static const char kLowMemMarginFile[] = + "/sys/kernel/mm/chromeos-low_mem/margin"; + +// NOTE: This is not the only version of this function in the source: +// the base library (in process_util_linux.cc) also has its own C++ version. bool AdjustOOMScore(pid_t process, int score) { if (score < 0 || score > kMaxOomScore) return false; @@ -71,3 +77,30 @@ bool AdjustOOMScore(pid_t process, int score) { close(fd); return (bytes_written == len); } + +bool AdjustLowMemoryMargin(int64_t margin_mb) { + int file_descriptor = open(kLowMemMarginFile, O_WRONLY); + if (file_descriptor < 0) + return false; + + // Only allow those values which are reasonable, to prevent mischief. + char value[21]; + switch (margin_mb) { + case -1L: + snprintf(value, sizeof(value), "off"); + break; + case 0L: + case 25L: + case 50L: + case 100L: + case 200L: + snprintf(value, sizeof(value), "%zu", margin_mb); + break; + default: + return false; + } + + bool success = (write(file_descriptor, value, strlen(value)) >= 0); + close(file_descriptor); + return success; +} diff --git a/sandbox/linux/suid/sandbox.c b/sandbox/linux/suid/sandbox.c index a83291e..41a68c7 100644 --- a/sandbox/linux/suid/sandbox.c +++ b/sandbox/linux/suid/sandbox.c @@ -4,6 +4,8 @@ // http://code.google.com/p/chromium/wiki/LinuxSUIDSandbox +#include "sandbox.h" + #define _GNU_SOURCE #include <asm/unistd.h> #include <errno.h> @@ -38,7 +40,6 @@ #define CLONE_NEWNET 0x40000000 #endif -static const char kAdjustOOMScoreSwitch[] = "--adjust-oom-score"; static const char kSandboxDescriptorEnvironmentVarName[] = "SBX_D"; static const char kSandboxHelperPidEnvironmentVarName[] = "SBX_HELPER_PID"; @@ -405,9 +406,10 @@ int main(int argc, char **argv) { // when you call it with --find-inode INODE_NUMBER. if (argc == 3 && (0 == strcmp(argv[1], kFindInodeSwitch))) { pid_t pid; - char* endptr; + char* endptr = NULL; + errno = 0; ino_t inode = strtoull(argv[2], &endptr, 10); - if (inode == ULLONG_MAX || *endptr) + if (inode == ULLONG_MAX || !endptr || *endptr || errno != 0) return 1; if (!FindProcessHoldingSocket(&pid, inode)) return 1; @@ -417,17 +419,31 @@ int main(int argc, char **argv) { // Likewise, we cannot adjust /proc/pid/oom_adj for sandboxed renderers // because those files are owned by root. So we need another helper here. if (argc == 4 && (0 == strcmp(argv[1], kAdjustOOMScoreSwitch))) { - char* endptr; + char* endptr = NULL; long score; + errno = 0; unsigned long pid_ul = strtoul(argv[2], &endptr, 10); - if (pid_ul == ULONG_MAX || *endptr) + if (pid_ul == ULONG_MAX || !endptr || *endptr || errno != 0) return 1; pid_t pid = pid_ul; + endptr = NULL; + errno = 0; score = strtol(argv[3], &endptr, 10); - if (score == LONG_MAX || score == LONG_MIN || *endptr) + if (score == LONG_MAX || score == LONG_MIN || + !endptr || *endptr || errno != 0) return 1; return AdjustOOMScore(pid, score); } +#if defined(OS_CHROMEOS) + if (argc == 3 && (0 == strcmp(argv[1], kAdjustLowMemMarginSwitch))) { + char* endptr = NULL; + errno = 0; + unsigned long margin_mb = strtoul(argv[2], &endptr, 10); + if (!endptr || *endptr || errno != 0) + return 1; + return AdjustLowMemoryMargin(margin_mb); + } +#endif if (!MoveToNewNamespaces()) return 1; diff --git a/sandbox/linux/suid/sandbox.h b/sandbox/linux/suid/sandbox.h new file mode 100644 index 0000000..e9ae90c --- /dev/null +++ b/sandbox/linux/suid/sandbox.h @@ -0,0 +1,24 @@ +// Copyright (c) 2012 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. + +#ifndef SANDBOX_LINUX_SUID_SANDBOX_H_ +#define SANDBOX_LINUX_SUID_SANDBOX_H_ +#pragma once + +#if defined(__cplusplus) +namespace sandbox { +#endif + +// These are command line switches that may be used by other programs +// (e.g. Chrome) to construct a command line for the sandbox. +static const char kAdjustOOMScoreSwitch[] = "--adjust-oom-score"; +#if defined(OS_CHROMEOS) +static const char kAdjustLowMemMarginSwitch[] = "--adjust-low-mem"; +#endif + +#if defined(__cplusplus) +} // namespace sandbox +#endif + +#endif // SANDBOX_LINUX_SUID_SANDBOX_H_ diff --git a/sandbox/linux/suid/suid_unsafe_environment_variables.h b/sandbox/linux/suid/suid_unsafe_environment_variables.h index 5862010..d216819 100644 --- a/sandbox/linux/suid/suid_unsafe_environment_variables.h +++ b/sandbox/linux/suid/suid_unsafe_environment_variables.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -13,6 +13,10 @@ // sysdeps/unix/sysv/linux/i386/dl-librecon.h // sysdeps/generic/unsecvars.h +#ifndef SANDBOX_LINUX_SUID_SUID_UNSAFE_ENVIRONMENT_VARIABLES_H_ +#define SANDBOX_LINUX_SUID_SUID_UNSAFE_ENVIRONMENT_VARIABLES_H_ +#pragma once + static const char* kSUIDUnsafeEnvironmentVariables[] = { "LD_AOUT_LIBRARY_PATH", "LD_AOUT_PRELOAD", @@ -57,3 +61,5 @@ static inline char* SandboxSavedEnvironmentVariable(const char* envvar) { return saved_envvar; } + +#endif // SANDBOX_LINUX_SUID_SUID_UNSAFE_ENVIRONMENT_VARIABLES_H_ diff --git a/sandbox/sandbox.gyp b/sandbox/sandbox.gyp index 50a9bfe..a3593c6 100644 --- a/sandbox/sandbox.gyp +++ b/sandbox/sandbox.gyp @@ -167,6 +167,7 @@ 'linux/suid/linux_util.h', 'linux/suid/process_util.h', 'linux/suid/process_util_linux.c', + 'linux/suid/sandbox.h', 'linux/suid/sandbox.c', ], 'cflags': [ |