Bug 782456, part 1: Let clients of GeckoChildProcessHost specify privileges. r=bent
authorChris Jones <jones.chris.g@gmail.com>
Wed, 29 Aug 2012 09:24:48 -0300
changeset 105797 8f22c4560de7c61a4e72c71cbefcce8c989aa349
parent 105796 cf396cb6d4af6f1110c4635f8e41db788d82931b
child 105798 dd12dcbb264b3598f1e3673394e054882b08785b
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersbent
bugs782456
milestone18.0a1
Bug 782456, part 1: Let clients of GeckoChildProcessHost specify privileges. r=bent
ipc/chromium/src/base/process_util.h
ipc/chromium/src/base/process_util_linux.cc
ipc/chromium/src/base/process_util_mac.mm
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/GeckoChildProcessHost.h
--- a/ipc/chromium/src/base/process_util.h
+++ b/ipc/chromium/src/base/process_util.h
@@ -121,16 +121,22 @@ ProcessId GetProcId(ProcessHandle proces
 // multi-threading.
 void SetAllFDsToCloseOnExec();
 // Close all file descriptors, expect those which are a destination in the
 // given multimap. Only call this function in a child process where you know
 // that there aren't any other threads.
 void CloseSuperfluousFds(const base::InjectiveMultimap& saved_map);
 #endif
 
+enum ChildPrivileges {
+  PRIVILEGES_DEFAULT,
+  PRIVILEGES_UNPRIVILEGED,
+  PRIVILEGES_INHERIT
+};
+
 #if defined(OS_WIN)
 // Runs the given application name with the given command line. Normally, the
 // first command line argument should be the path to the process, and don't
 // forget to quote it.
 //
 // If wait is true, it will block and wait for the other process to finish,
 // otherwise, it will just continue asynchronously.
 //
@@ -155,20 +161,16 @@ bool LaunchApp(const std::wstring& cmdli
 // Note that the first argument in argv must point to the filename,
 // and must be fully specified.
 typedef std::vector<std::pair<int, int> > file_handle_mapping_vector;
 bool LaunchApp(const std::vector<std::string>& argv,
                const file_handle_mapping_vector& fds_to_remap,
                bool wait, ProcessHandle* process_handle);
 
 typedef std::map<std::string, std::string> environment_map;
-enum ChildPrivileges {
-  UNPRIVILEGED,
-  SAME_PRIVILEGES_AS_PARENT
-};
 bool LaunchApp(const std::vector<std::string>& argv,
                const file_handle_mapping_vector& fds_to_remap,
                const environment_map& env_vars_to_set,
                ChildPrivileges privs,
                bool wait, ProcessHandle* process_handle,
                ProcessArchitecture arch=GetCurrentProcessArchitecture());
 bool LaunchApp(const std::vector<std::string>& argv,
                const file_handle_mapping_vector& fds_to_remap,
--- a/ipc/chromium/src/base/process_util_linux.cc
+++ b/ipc/chromium/src/base/process_util_linux.cc
@@ -180,17 +180,17 @@ bool LaunchApp(const std::vector<std::st
 }
 
 bool LaunchApp(const std::vector<std::string>& argv,
                const file_handle_mapping_vector& fds_to_remap,
                const environment_map& env_vars_to_set,
                bool wait, ProcessHandle* process_handle,
                ProcessArchitecture arch) {
   return LaunchApp(argv, fds_to_remap, env_vars_to_set,
-                   SAME_PRIVILEGES_AS_PARENT,
+                   PRIVILEGES_INHERIT,
                    wait, process_handle);
 }
 
 bool LaunchApp(const std::vector<std::string>& argv,
                const file_handle_mapping_vector& fds_to_remap,
                const environment_map& env_vars_to_set,
                ChildPrivileges privs,
                bool wait, ProcessHandle* process_handle,
@@ -226,17 +226,17 @@ bool LaunchApp(const std::vector<std::st
       _exit(127);
 
     CloseSuperfluousFds(fd_shuffle2);
 
     for (size_t i = 0; i < argv.size(); i++)
       argv_cstr[i] = const_cast<char*>(argv[i].c_str());
     argv_cstr[argv.size()] = NULL;
 
-    if (privs == UNPRIVILEGED) {
+    if (privs == PRIVILEGES_UNPRIVILEGED) {
       if (setgid(CHILD_UNPRIVILEGED_GID) != 0) {
         DLOG(ERROR) << "FAILED TO setgid() CHILD PROCESS, path: " << argv_cstr[0];
         _exit(127);
       }
       if (setuid(CHILD_UNPRIVILEGED_UID) != 0) {
         DLOG(ERROR) << "FAILED TO setuid() CHILD PROCESS, path: " << argv_cstr[0];
         _exit(127);
       }
--- a/ipc/chromium/src/base/process_util_mac.mm
+++ b/ipc/chromium/src/base/process_util_mac.mm
@@ -38,17 +38,17 @@ bool LaunchApp(const std::vector<std::st
 }
 
 bool LaunchApp(const std::vector<std::string>& argv,
                const file_handle_mapping_vector& fds_to_remap,
                const environment_map& env_vars_to_set,
                bool wait, ProcessHandle* process_handle,
                ProcessArchitecture arch) {
   return LaunchApp(argv, fds_to_remap, env_vars_to_set,
-                   SAME_PRIVILEGES_AS_PARENT,
+                   PRIVILEGES_INHERIT,
                    wait, process_handle);
 }
 
 bool LaunchApp(const std::vector<std::string>& argv,
                const file_handle_mapping_vector& fds_to_remap,
                const environment_map& env_vars_to_set,
                ChildPrivileges privs,
                bool wait, ProcessHandle* process_handle,
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -70,22 +70,23 @@ ShouldHaveDirectoryService()
 template<>
 struct RunnableMethodTraits<GeckoChildProcessHost>
 {
     static void RetainCallee(GeckoChildProcessHost* obj) { }
     static void ReleaseCallee(GeckoChildProcessHost* obj) { }
 };
 
 GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
-                                             base::WaitableEventWatcher::Delegate* aDelegate)
+                                             ChildPrivileges aPrivileges)
   : ChildProcessHost(RENDER_PROCESS), // FIXME/cjones: we should own this enum
     mProcessType(aProcessType),
+    mPrivileges(aPrivileges),
     mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
     mProcessState(CREATING_CHANNEL),
-    mDelegate(aDelegate),
+    mDelegate(nullptr),
     mChildProcessHandle(0)
 #if defined(MOZ_WIDGET_COCOA)
   , mChildTask(MACH_PORT_NULL)
 #endif
 {
     MOZ_COUNT_CTOR(GeckoChildProcessHost);
     
     MessageLoop* ioLoop = XRE_GetIOMessageLoop();
@@ -434,19 +435,21 @@ GeckoChildProcessHost::PerformAsyncLaunc
   // For POSIX, we have to be extremely anal about *not* using
   // std::wstring in code compiled with Mozilla's -fshort-wchar
   // configuration, because chromium is compiled with -fno-short-wchar
   // and passing wstrings from one config to the other is unsafe.  So
   // we split the logic here.
 
 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD)
   base::environment_map newEnvVars;
-  base::ChildPrivileges privs = kLowRightsSubprocesses ?
-                                base::UNPRIVILEGED :
-                                base::SAME_PRIVILEGES_AS_PARENT;
+  ChildPrivileges privs = mPrivileges;
+  if (privs == base::PRIVILEGES_DEFAULT) {
+    privs = kLowRightsSubprocesses ?
+            base::PRIVILEGES_UNPRIVILEGED : base::PRIVILEGES_INHERIT;
+  }
   // XPCOM may not be initialized in some subprocesses.  We don't want
   // to initialize XPCOM just for the directory service, especially
   // since LD_LIBRARY_PATH is already set correctly in subprocesses
   // (meaning that we don't need to set that up in the environment).
   if (ShouldHaveDirectoryService()) {
     nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
     NS_ASSERTION(directoryService, "Expected XPCOM to be available");
     if (directoryService) {
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -21,20 +21,21 @@ namespace ipc {
 
 class GeckoChildProcessHost : public ChildProcessHost
 {
 protected:
   typedef mozilla::Monitor Monitor;
   typedef std::vector<std::string> StringVector;
 
 public:
+  typedef base::ChildPrivileges ChildPrivileges;
   typedef base::ProcessHandle ProcessHandle;
 
-  GeckoChildProcessHost(GeckoProcessType aProcessType=GeckoProcessType_Default,
-                        base::WaitableEventWatcher::Delegate* aDelegate=nullptr);
+  GeckoChildProcessHost(GeckoProcessType aProcessType,
+                        ChildPrivileges aPrivileges=base::PRIVILEGES_DEFAULT);
 
   ~GeckoChildProcessHost();
 
   static nsresult GetArchitecturesForBinary(const char *path, uint32 *result);
 
   static uint32 GetSupportedArchitecturesForProcessType(GeckoProcessType type);
 
   // Block until the IPC channel for our subprocess is initialized,
@@ -93,16 +94,17 @@ public:
   task_t GetChildTask() {
     return mChildTask;
   }
 #endif
 
 
 protected:
   GeckoProcessType mProcessType;
+  ChildPrivileges mPrivileges;
   Monitor mMonitor;
   FilePath mProcessPath;
   // This value must be accessed while holding mMonitor.
   enum {
     // This object has been constructed, but the OS process has not
     // yet.
     CREATING_CHANNEL = 0,
     // The IPC channel for our subprocess has been created, but the OS