Maximize RLIMIT_AS resource limit in nacl_helper child before exec

NaCl processes need an unusually large amount of address space, because
they do huge PROT_NONE mappings to reserve contiguous regions much larger
than the memory that will actually be used.  An ambient RLIMIT_AS setting
can break this, so we need to raise the soft limit to the hard limit (which
is usually unlimited).

We cannot rely on doing this inside the nacl_helper child itself, so we
must do it in the zygote before it exec's nacl_helper_bootstrap.  That exec
itself could fail if the limit is too small, because nacl_helper_bootstrap
uses ELF program headers to reserve a large region of address space.

BUG= http://code.google.com/p/nativeclient/issues/detail?id=2438
TEST= nacl apps work when "ulimit -S -v 5376320" was run before starting chrome

[email protected],[email protected],[email protected]

Review URL: http://codereview.chromium.org/8528041

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110123 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc
index 055edcc1..79ce1f7 100644
--- a/base/process_util_posix.cc
+++ b/base/process_util_posix.cc
@@ -630,6 +630,24 @@
       }
     }
 
+    if (options.maximize_rlimits) {
+      // Some resource limits need to be maximal in this child.
+      std::set<int>::const_iterator resource;
+      for (resource = options.maximize_rlimits->begin();
+           resource != options.maximize_rlimits->end();
+           ++resource) {
+        struct rlimit limit;
+        if (getrlimit(*resource, &limit) < 0) {
+          RAW_LOG(WARNING, "getrlimit failed");
+        } else if (limit.rlim_cur < limit.rlim_max) {
+          limit.rlim_cur = limit.rlim_max;
+          if (setrlimit(*resource, &limit) < 0) {
+            RAW_LOG(WARNING, "setrlimit failed");
+          }
+        }
+      }
+    }
+
 #if defined(OS_MACOSX)
     RestoreDefaultExceptionHandler();
 #endif  // defined(OS_MACOSX)