diff options
author | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-03 20:30:43 +0000 |
---|---|---|
committer | gspencer@chromium.org <gspencer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-03 20:30:43 +0000 |
commit | 232ed4691df490e376c74ecf04f2f6092f03427f (patch) | |
tree | 3dd09707acccf9eb175e592b4f0fbade06a5015b /sandbox | |
parent | 9a4fd693db2ee9e383f7a826d50bc63bc5bf7db0 (diff) | |
download | chromium_src-232ed4691df490e376c74ecf04f2f6092f03427f.zip chromium_src-232ed4691df490e376c74ecf04f2f6092f03427f.tar.gz chromium_src-232ed4691df490e376c74ecf04f2f6092f03427f.tar.bz2 |
This creates a field trial to determine the best level for low memory
notification.
It creates a field trial with 7 groups: default (kernel default
value), turning notification off (relying on OOM killer only), 0MB, 25MB, 50MB
margin, 100MB margin, and 200MB margin.
Also, in order to set parameters for the trial, this CL creates
an API for setting the low memory margin.
BUG=chromium-os:20080
TEST=Ran on device several times, checked that the memory margin was
set correctly when the session started, and that different trial groups
were selected.
Review URL: http://codereview.chromium.org/10206029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135205 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sandbox')
-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 |
6 files changed, 96 insertions, 9 deletions
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': [ |